4 ms·
> Next we add some methods to the Bob struct. `impl Bob` defines methods inherent to the type; `impl Drop for Bob` implements methods defined by the Drop trait
by Twisol 12y ago
> Next we add some methods to the Bob struct.
`impl Bob` defines methods inherent to the type; `impl Drop for Bob` implements methods defined by the Drop trait. (Think Java interfaces.)
> I get the sinking feeling [...]
`{name: name}` works just fine.
> I'm going to guess 'drop' is a special case [...]
Since the signature for `drop` is defined elsewhere, by the `Drop` trait, we must use `&mut`, regardless of if we actually mutate `self`.
> Why must 'f' be 'mut' here?
This time the trait is `Show`, and the same reason as for `Drop` applies. Now, however, we're actually using the fact that it's `mut`: you can't write to an immutable formatter.
> Why is the '&mut' before the type and not before the name?
Because mutability and ownership is information carried by the type, not by the value.
> It seems weird there's not just one place to put the 'mut' flag.
You use `mut` to define whether a stack-allocated value can be mutated, and also to define whether a reference can be used to mutate its referent. Function parameters are stack-allocated, so you can put `mut` before them in the parameter list.
> Up until this point string handling seems reasonably sane.
`String` is a resizable string. `str` is not. It's a bit like Vec<T> vs. [T] - see http://cosmic.mearie.org/2014/01/periodic-table-of-rust-types/ http://cosmic.mearie.org/2014/01/periodic-table-of-rust-type... .
> I think I spoke too soon, because further down [...]
That incantation effectively disables Rust's compile-time ownership checking and replaces it with a runtime-checked structure. RefCell implements `&mut` semantics at runtime, and Rc allows multiple owners of the same data. There are often ways to avoid needing these constructs, and it's considered a code smell, so the incantation is long for a good reason. (If you really want a shorter version, you can use `unsafe {}` and raw pointers. Or C++.)
You can have a mutable heap-allocated value simply by using `Box::new` and marking the stack variable as `mut`: `let mut foo = Box::new(Bob::new("A"))` .
I agree that the syntax sometimes isn't quite there. There used to be a `box` keyword for heap allocations, but it's been feature-gated for the alpha.