Hacker News new | ask | show | jobs
by tialaramex 1650 days ago
Rust doesn't end up with an overloadable copy assignment operator, it does something else which I would argue is cleverer (although you can't just add it to an existing language)

Because Rust knows the lifetime of everything in your program (in Rust the lifetime of things is part of their type) the effect of the assignment operator = is to dispose of whatever was in the variable before, and move the assigned item into the variable.

Rust's Copy trait does not alter the semantics of the assignment operators - you can't overload that. You promise that your type's in-memory representation is all that matters, and then if you move from a variable the value in that variable is still live even though there was a copy made, usually that value would be dead because it was moved from.

Rust's Clone trait behaves a little like a C++ copy constructor, except, it's an explicit trait, the only way to get a clone of x is to x.clone() or various moral equivalents e.g. Clone::clone(&x); so you're not getting one without explicitly asking for it.

Rust doesn't formally have Constructors, or from another perspective, any Rust code anywhere which wants to make a Thing, is a "Constructor" for that Thing. (safe) Rust won't let you do any of the shenanigans which is common in C++ like having two separate pieces of code share responsibility for initialising a data structure, in Rust when you make a Thing you need to explicitly set all the values in the Thing at once, if the easy way to write that involves temporaries, no matter the compiler does have an optimiser and knows how to use it.

It is idiomatic in Rust to provide a function named new() in the implementation of a structure which will make you one of that structure if doing so makes sense, but that function and its name aren't magic, it's just a convention. Rust's vector type Vec has a new() function but it also has a with_capacity(n) function, they're both "Constructors" in the C++ sense if you want to think about it that way, with_capacity() isn't calling new() to make the vector, that would be crazy.

1 comments

Worth noting that even though Rust doesn't let you have two separate pieces of code share responsibility for actually initializing a data structure, in practice that doesn't lead to much, if any, code duplication: a Foo::new() can usually be written as a wrapper around a call to Foo::new_with_options(x, y, z).