美文网首页
Rust范型与Unsize类型

Rust范型与Unsize类型

作者: 黑天鹅学院 | 来源:发表于2021-10-01 08:13 被阅读0次

    概念

    Sized是Rust编译阶段检查对象操作的一个基本依据,Rust只允许操作已知大小的对象, 未知大小的对象只能操作它的指针(&)。

    默认情况下,任何类型参数都是Sized限定的,即:

    <T> 等价于 <T: Sized>
    

    在Rust里,如果一个类型的字节大小在编译期可以确定,那么这个类型就是确定大小(Sized)的。确定类型的大小(size)对于能够在栈(stack)上为实例分配足够的空间是十分重要的。确定大小类型(sized type)可以通过传值(by value)或者传引用(by reference)的方式来传递。

    如果一个类型的大小不能在编译期确定,那么它就被称为不确定大小类型(unsized type)或者DST,即动态大小类型(Dynamically-Sized Type)。因为不确定大小类型(unsized type)不能存放在栈上,所以它们只能通过传引用(by reference)的方式来传递。

    示例代码

    以下代码是正确的:

    fn sized_correct() {
        #[derive(Debug)]
        struct Water<T>(T);            // 等同于 struct Status<T: Sized>(T);
    
        #[derive(Debug)]
        struct Cup(Water<i32>);
    
        let water = Water(10);
        let cup = Cup(water);
        println!("{:?}", cup);         // output: Cup(Water(10))
    }
    

    以下代码是错误的:

    fn sized_error() {
        #[derive(Debug)]
        struct Water<T>(T);            // 等同于 struct Status<T: Sized>(T);
    
        #[derive(Debug)]
        struct Cup(Water<[i32]>);     // 由于[i32] 是一个队列, 因此它是未知大小
    }
    
    

    为了支持参数长度可变,需要进行调整:

    fn use_unsized_to_fix_sized_error() {
        #[derive(Debug)]
        #[allow(dead_code)]
        struct Bar<T: ?Sized>(T);
    
        #[derive(Debug)]
        #[allow(dead_code)]
        struct BarUse<'a>(Bar<&'a [i32]>);
    }
    

    尽管[i32]是可变长度变量,但是&[i32]是一个指针,长度是固定的,在加入?Sized约束后,Bar中使用到的范型可以是可变长度变量。

    在Rust中,指向数组的动态大小视图(dynamically sized views)被称为切片(slice)。例如,一个&str是一个"字符串切片(string slice)" ,一个&[i32]是一个"i32切片"。切片(slice)是双宽度(double-width)的,因为他们存储了一个指向数组的指针和数组中元素的数量。

    trait对象指针是双宽度(double-width)的,因为他们存储了一个指向数据的指针和一个指向vtable的指针。

    不确定大小(unsized) 结构体指针是双宽度的,因为他们存储了一个指向结构体数据的指针和结构体的大小(size)。不确定大小(unsized) 结构体只能拥有有1个不确定大小(unsized)字段(field)而且它必须是结构体里的最后一个字段(field)。

    总结

    只有确定大小类型(sized type)的实例可以被放到栈上,也就是,可以通过值传递。

    不确定大小类型(unsized type)的实例不能被放置在栈上并且必须通过引用来传递。

    不确定大小类型(unsized type)的指针是双宽度(double-width)的,因为除了指向数据之外,他们还需要做一些额外的记录来追踪数据的长度或者指向一个vtable。

    相关文章

      网友评论

          本文标题:Rust范型与Unsize类型

          本文链接:https://www.haomeiwen.com/subject/surmiltx.html