It actually works quite well. It's not without its quirks, but unique_ptr is really great. If you think there are holes in unique_ptr, then write an article with some good examples, I'll be the first to read it.
Rust hasn't seen enough widespread use to find all the problems and limitations with the language. The borrow checker seems great, sure. But looking at how Rust handles moves vs copies, I'm not convinced at all that it will be good enough in the long run.
This "mess" is caused by imbuing Example with correct move and copy semantics. In rust, it seems like most types have one or the other, but not both. If a type does not implement Copy, then when you try to copy it, it automatically gets moved from. So u = v would change the value of v. Ironically, that's similar to the behavior of auto_ptr that you just criticized, and quite unintuitive.
Note that while C++ zeroes on move, in Rust the compiler statically prevents you from using v after the move. The only way to use v afterwards is to move something new into it (which can only be done if v is mutable). Semantically, a move is a memcpy, except the source is inaccessible after the move.
Right, which is great, don't get me wrong. If you're going to have that behavior, having the compiler enforce it is good.
I just think it's a bit amusing, people complain about this sort of thing in C++ all the time. I can imagine if Rust takes over people will complain how you have no idea what u = v is doing unless you know what u and v are.
I'll admit my biases, but I prefer the c++ way: types know how to both move and copy themselves, and they will copy by default, but move when it's safe (rvalue) or explicitly asked to (std::move). I like looking at auto u = v and knowing that u is always a copy of v.
u = v is always the same thing in Rust: semantically a shallow byte copy ala memcpy (although there may not actually be a byte-by-byte copy at runtime, due to optimisations etc.). Whether a type moves or copies doesn't change this, it only influences whether v is usable (statically checked) after the assignment: the worst that happens if you don't know what type they are is a compile error talking about "use of moved value" (which also points to exactly the place that did the move).
The `Copy` trait (types that don't move) is just for types where memcpy is a valid & safe way to duplicate values of those types, it's not at all like C++'s custom copy constructors.
Well, if you have let u = v.clone(); then you are absolutely certain that u is a copy of v too (And it works on more types than just simple copying would).
Yes, of course you can do that, but you lose certain things. In C++ you can write code (e.g constructors) that will do the right thing with their arguments, move or copy, based on whether the input is an rvalue or not. Is there a way to get this behavior in rust?
In Rust, move semantics are assumed by default, and it's up to the caller to make a copy using .clone() if they want to keep ownership of the value (unless they know Copy is implemented and it's unnecessary, for example for integer types).
Rust hasn't seen enough widespread use to find all the problems and limitations with the language. The borrow checker seems great, sure. But looking at how Rust handles moves vs copies, I'm not convinced at all that it will be good enough in the long run.
This "mess" is caused by imbuing Example with correct move and copy semantics. In rust, it seems like most types have one or the other, but not both. If a type does not implement Copy, then when you try to copy it, it automatically gets moved from. So u = v would change the value of v. Ironically, that's similar to the behavior of auto_ptr that you just criticized, and quite unintuitive.