美文网首页
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类型

    概念 Sized是Rust编译阶段检查对象操作的一个基本依据,Rust只允许操作已知大小的对象, 未知大小的对象只...

  • CoreJava笔记 - 范型程序设计(5)

    反射与范型 由于类型擦除,反射无法得到关于范型类型参数的信息。 范型的Class类在Java的反射库中,Class...

  • Rust范型(1) - 范型基础

    简介 C/C++、Rust都属于强类型语言,在定义变量或者是传参时,必须明确指定数据的数据类型。明确指定类型对于程...

  • Rust范型(2) - 范型约束

    trait中的范型 在定义trait时,可以使用范型: Dagongren是一个trait,包含了banzhuan...

  • Rust语言编程实例100题-065

    Rust语言编程实例100题-065 题目:泛型练习。泛型并不是Rust特有的概率,在很多强类型的编程语言中也支持...

  • CoreJava笔记 - 范型程序设计(2)

    范型代码和Java虚拟机 关键知识:类型擦除Java的范型是编译器层次的范型,而在Java虚拟机上并没有范型类。在...

  • 3.2 数据类型

    标量scalar 标量(scalar)类型代表一个单独的值。Rust 有四种基本的标量类型:整型、浮点型、布尔类型...

  • java获取范型参数类型

    JAVA中不能直接获取范型参数类型,如下: 实际开发中有可能出现需要根据List中范型参数类型(如strLists...

  • java基础知识梳理&泛型初探

    目录 概述 范型的使用 类型参数 类型通配符 泛型方法 泛型类 限定类型参数上限 上界通配符(Upper Boun...

  • Kotlin范型摘要

    范型类型参数 声明范型类型 你还可以用同样的语法声明泛型的扩展属性。 可以给类或接口的方法、顶层函数,以及扩展函数...

网友评论

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

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