Total beginner here: I can understand it accepting a &string, as read_line should mutate the variable's data, but why would it need to change where the variable is pointing to?
It's not; &mut String
is a reference to a mutable string; mut &String
would be a mutable reference to an immutable string.
interesting. I was going through the tutorial and the "guess" variable was already stated to be mutable. Why is it necessary to do so again?
The String
is owned by its binding: guess
. &
and &mut
let you borrow that String
.
&guess
is an immutable reference. It gives you a "read access" but that's all.
&mut guess
is a mutable reference. It lets you mutate the object owned by the binding guess
.
You may want to lookup the chapter 4 of the book on Ownership.
How mutability works in Rust is central to its design, so I guess you will see more of it and understand it in its context as you go along.
In brief, mutable access means exclusive access, and even if you have a mutable variable for a string, you might not want to give a particular function you call exclusive access to it -- not if you need something else to read from the same variable concurrently, for example.
Rust has already chosen to make passing references explicit (must use & / &mut syntax to pass a reference to a variable), and which kind of reference is also explicit — maybe because it matters for the borrow checker (the part of the compiler that checks the rules for references).
You can replace a &mut
reference using std::mem::replace
, which is safe.
Others have already said this, but the mut
modifier is for the owner of the value - it allows them to mutate the value. They can also lend it out immutably to other places, but those cannot modify it. They can also lend it out mutably, which allows modification by a single possessor of the mutable borrow. If the owner doesn't declare the value as mutable to begin with, no mutable borrows are allowed either. So ownership and mutability are front and center in Rust, it's very explicit about them.
And replace
is a safe wrapper around unsafe code, which I specifically said could do that. My point was that references should be thought of as borrowings, not as pointers, although they are.
Ok fair enough
Sorry, but that's misleading. With that argument all of std
is a safe wrapper around unsafe code somewhere.
Fact is, mem::replace
is a safe standard function and there is nothing at all unsafe about using it to replace the object referenced by a &mut
reference.
That's how I looked at it initially as well, but technically it's right - it requires unsafe code internally; if no such function existed, you'd implement it via unsafe since it's not expressible in the language itself.
It's just the swapping out of the old value that's not expressible without the function. If you just want to replace the referenced object, *ref = newvalue
does not need a function.
That's true. For some reason I thought we were talking about replacement in the mem::replace
sense, but maybe I read too much into it.
I guess we come from different perspectives. In Rust I find you're often not supposed to think in terms of pointers. I meant to provide a proper thought model and have it contrast with the way C and C++ do things. Sort of a "pedagogy comes before technically-correct" if you will.
That's a good perspective to have, but with respect to mutable references, I'd leave the comparison to raw pointers in C/C++ at "guaranteed non-null and guaranteed to be unique (i.e. no other read/write aliasing)" (with "guaranteed" being modulo nobody doing unsafe things). That alone is quite powerful. The replacement portion is confusing and possibly inaccurate, depending on how one interprets it (as witnessed in this thread).
Yeah, fair enough. I've edited my answer not to mislead anyone.
Well, the whole point of read_line is that it gets the command line input and it puts it in the location specified by "string", like you said. "Mut &string" means the reference can be changed while "&mut string" means that the actual string can be changed.
I like to think of references as portals into the actual variable, so this means that you can change the variable that you have the portal to!
I had the same question - thank you so much for asking!
Please do not bump old threads.
This topic was automatically closed 7 days after the last reply. We invite you to open a new topic if you have further questions or comments.