在 Rust 中,如果你执行以下操作:
let v1 = String::from("hello");
let v2 = v1;
println!("{}", v1);
你会得到一个编译器错误,因为 Rust 中的=
执行移动,而不是复制或"共享"。
我正在阅读这篇文章,其中更详细地讨论了这个问题:
但还有一个更大的问题,关于释放。如果使用共享语义,则
v1
和v2
都将拥有单个数据缓冲区,因此当它们被解除分配时,同一堆缓冲区将被释放两次。缓冲区不能分配两次,否则会导致内存损坏并导致程序故障。为了解决这个问题,使用共享语义的语言不会在变量范围的末尾使用这种内存来释放内存,而是诉诸垃圾回收。
我的问题是,当v1
和v2
超出范围时,为什么需要释放两次数据缓冲区?除了"破坏"v1
和v2
之外,我们不能只释放一次数据缓冲区吗?我知道v1
和v2
实际上是值而不是引用,但是不将它们作为具有上述行为的"智能引用"的理由是什么?
[...] 不将它们作为"智能引用"的理由是什么?
主要是性能。Rust 是关于"零成本抽象"(C++创造的一个术语(。如果程序员不需要该语言,则不应产生运行时开销。这样的"智能引用"将是引用计数的指针(如 Rust 中的Rc
或Arc
,或 C++ 中的shared_ptr
(,或者需要垃圾回收器。这两种解决方案都有此开销。