| > Lifetimes - implicit/explicit semantics for how long a name is considered alive, whereas in C++ there would be a delete or falling out of scope. In Rust there's a move or a falling out of scope. Lifetimes are passive, and just describe the connection between references so that the compiler can check that they don't become dangling when values are destroyed in essentially the same places as C++ would destroy them. > Borrowing - I still don't understand how or why a non-reference is implicitly consumed by passing it (read-only intention) by value(?) to another function and then can't be used again. Pony does explicit consumption. Rust had a more pony-like model with annotations and different modes many years ago, but the model was unnecessarily complicated and was simplified to a "everything is pass-by-value" one: - http://smallcultfollowing.com/babysteps/blog/2011/12/08/why-... - http://smallcultfollowing.com/babysteps/blog/2012/10/01/move... Things to know: - Rust has no copy constructors (but does have a "this can be safely semantically duplicated by memcpy" marker trait (Copy), which cannot run arbitrary code. See https://stackoverflow.com/a/31013156/1256624 and https://stackoverflow.com/a/24253573/1256624.) - A "move" is a memcpy (bitwise copy) of a value to a new location, where the source becomes inaccessible at compile time - A "read-only" T is a separate type &T, which is a value in its own right (and &_ implements Copy, so can be passed-by-value multiple times without explicit copies). - Every value of type T is always a fully-fledged T, with all of T's operations available - Parameters of type T (e.g. fn f(x: T)) are thus full values - For an arbitrary type T, there's no way to (implicitly) copy values of type T, so the only way to call a function with a T parameter is to have the callee take ownership/responsibility for the caller's T value (i.e. move it into the call) |