From the Rust book about how to mutate struct fields:
let mut point = Point { x: 0, y: 0 };
point.x = 5;
and later:
Mutability is a property of the binding, not of the structure itself.
This seems counter-intuitive to me because point.x = 5
doesn't look like I'm rebinding the variable point
. Is there a way to explain this so it's more intuitive?
The only way I can wrap my head around this is to "imagine" that I'm rebinding point
to a copy of the original Point
with a different x
value (not even sure that's accurate).
I had the same confusion. For me it came from two separate misunderstandings. First, I came from a language where variables (aka bindings) were implicitly references to values. In that language it was important to distinguish between mutating the reference, and mutating the value that was referred to. Second, I thought by "the structure itself" the book was referring to the instantiated value, but by "the structure" it means the specification/declaration, not a particular value of that type.
Variables in Rust are different. From the reference:
A variable is a component of a stack frame...
A local variable (or stack-local allocation) holds a value directly, allocated within the stack's memory. The value is a part of the stack frame.
So a variable is a component of a stack frame -- a chunk of memory -- that directly holds the value. There is no reference to distinguish from the value itself, no reference to mutate. The variable and the value are the same hunk of memory.
A consequence is that rebinding a variable in the sense of changing it to refer to a different hunk of memory is not compatible with Rust's memory model. (n.b. let x = 1; let x = 2;
creates two variables.)
So the book is pointing out that mutability is declared at the "per hunk of memory" level rather than as part of the definition of a struct.
The only way I can wrap my head around this is to "imagine" that I'm rebinding point to a copy of the original Point with a different x value (not even sure that's accurate)
Instead imagine you are changing one of the 0's in a hunk of memory to a 5; and that that value resides within the memory designated by point
. Interpret "the binding is mutable" to mean that you can mutate the hunk of memory designated by the binding, including mutating just part of it, e.g. by setting a struct field. Think of rebinding Rust variables in the way that you describe as not expressible within Rust.