在 Rust 中,引用实际上是一个原始指针,对其使用方式有限制,就像 C++ 中的引用一样。
type T = i64;
let my_variable: &T;
在 C++ 中,与原始指针不同,引用不能是
nullptr
(指向地址 0
),并且必须在创建时对其进行初始化。从广义上讲,Rust 也是如此。
在 Rust 中,
Box
类型实际上是一个智能指针,类似于 C++ std::unique_ptr
。
关于特质的主题,在 C++ 中没有直接类比:
我们可以使用显式引用将特征对象传递给函数。
trait Trait;
fn func(arg: &dyn Trait);
但是,以下内容无法编译:
trait Trait;
fn func(arg: dyn Trait);
原因是这样的:
arg: doesn't have a size known at compile-time
看起来
dyn Trait
本身并不是一个胖指针,而是“参考”版本&dyn Trait
是?
装箱特征确实可以编译...
fn func(arg: Box<dyn Trait>)
问题是为什么?我不完全确定这个问题特别有意义。不管怎样,Rust 编译器似乎以某种特殊的方式对待 Box。
我本来希望看到这个:
fn func(arg: Box<&dyn Trait>)
事实上,这似乎也可以编译。
那么 - 这两种情况有什么区别?
Box<dyn Trait>
Box<&dyn Trait>
和
dyn Trait
- (不是一个有意义的概念)?&dyn Trait
dyn Trait
更类似于概念模板约束。虽然你需要一个 Box<dyn Trait>
,因为 Rust 只需要在非模板/非泛型函数上使用相同大小的对象(1 个函数对应 1 个布局,N 个函数对应 N 个布局)。这是因为 Box
或多或少是一个指针,因此任何类型的大小都是相同的。