sakana-boy
sakana-boy

Reputation: 35

Why is the default behavior in Rust to perform a move on assignment rather than just create another "reference" to the value?

In Rust if you do the following:

let v1 = String::from("hello");
let v2 = v1;
println!("{}", v1);

You will get a compiler error because = in Rust performs a move, rather than a copy or a "share".

I was reading this article where it discusses this in more detail:

But there is a bigger problem, regarding deallocation. If share semantics was used, both v1 and v2 would own the single data buffer, and so when they are deallocated, the same heap buffer would be deallocated twice. A buffer cannot be allocated twice, without causing memory corruption and consequently program malfunction. To solve this problem, the languages that use share semantics do not deallocate memory at the end of the scope of the variable using such memory, but resort to garbage collection.

My question is, when v1 and v2 go out of scope, why would it be necessary to free the data buffer twice? Couldn't we just free the data buffer once in addition to "destroying" v1 and v2? I understand that v1 and v2 are actually values and not references, but what is the rationale for not making them "smart references" that have the above behavior?

Upvotes: 1

Views: 230

Answers (1)

Lukas Kalbertodt
Lukas Kalbertodt

Reputation: 88536

[...] what is the rationale for not making them "smart references"?

Performance, mostly. Rust is all about "zero cost abstractions" (a term coined by C++). The language should not incur runtime-overhead if the programmer does not need it. Such "smart references" would be reference-counted pointers (like Rc or Arc in Rust, or shared_ptr in C++) or would require a garbage collector. Both of these solutions do have this overhead.

Upvotes: 3

Related Questions