Rust 中存在 DST(Dynamic Sized Type) 的概念。DST 是指在编译期无法确定大小的变量。但是 Rust 只能创建非 DST 变量 。使用 DST 指针指向 DST 类型是一个很好的做法。在 Rust 中,DST 指针不同于常规指针,其本身是一个携带了额外信息的胖指针。
在 Rust 中一共有四种 DST。
切片和字符串
和 C 语言中的字符串只是简单的 char\* 或是 char[] 不同。Rust 使用 str 作为字符串的基本类型。和 C 不同,Rust 中的 str 不仅携带了字符串的指针地址,还携带了 str 的长度信息。一个指向 str 的胖指针结构类似如下:
struct StrRef{
char* ptr;
size_t len;
};
由于 len 的值不确定,因而 str 是一个 DST 类型。
str 是切片的一种,自然的,切片也是一个 DST 类型。其指针结构与 str 相同:
struct SliceRef {
ptr: *const u32,
len: usize,
}
其中 len 储存了字符串的长度。由于其指针是常规指针的两倍大小,因而被称为 胖指针 。
特征对象
Rust 中的特征起着 C++ 中继承的作用。一方面其用来限制子类接口,另一方面也用来实现动态绑定。
函数无法返回特征对象,因为特征对象代表了一类实现了特征的类。这些类的大小不确定,因而只能返回指针。
特征对象的指针包含了一个虚函数指针,用来确定调用特征方法时实际需要调用的函数。
TIPS: Rust 借助特征对象实现了动态绑定。
自定义 DST
通过定义最后一个字段为 DST 的结构可以用来创建自己的 DST。不过,这种情况很少见。一个著名的例子是 std::path::Path
。
指向自定义DST的引用或指针也是胖指针。附加数据取决于结构内部DST的类型。