This might be the first time I’ve seen a good use for &mut &T, very cool!
For those of you not well-versed in Rust, this is a mutable pointer to an immutable string. This means that you can change the part of the string you’re pointing at, but you can’t change the underlying string itself.
What does that mean? Is it equivalent to the pointer starting out (say) pointing to the first letter of the string, but being able to "walk"/iterate along the length of the string?
EDIT: adjusted the diagram to make it more clear that we're not mutating the &str
Here's some string data, in memory somewhere:
Hello world
A `&str` is a pointer, length combo. The pointer points to the start of the string, the length says how many bytes there are:
(p, 11)
|
\
|
V
Hello world
A `&mut T` is a pointer, so a `&mut &str` looks like this:
p
|
V
(p, 11)
|
\
|
V
Hello world
Since it's mutable, this means we can re-assign what it points to, and create a new `&str` to the later part of the string:
p
\------\
V
(p, 11) (p, 5)
| |
\ |
| |
V V
Hello world
Since the inner &str is immutable, we can't change the underling string.
Hope that helps!
Re: your edit, isn't mutating the `&str` exactly what we're doing? Your new diagram implies that `input` itself is mutable and that's what's being overwritten, but that's not what `input: &mut &str` means nor would it even work because the mutation wouldn't be visible to the caller...?
I want to make sure I understand this. The original pointer &str does not own the "Hello world" variable but is a reference to it. The new &mut T pointer takes ownership of the &str reference so the original specified (p,11) would be destroyed/overwritten when changed to (p,5). The &mut T cannot edit the underlying string because it the reference it owns is a nonmutable reference. Even if the underlying string, "Hello world" was a mutable str variable, then &mut T could not access it since it was provided and immutable reference &str as its type.
If we provided a mutable pointer to the &mut T, would the mutable pointer would take ownership of the "Hello world"? If so, would Rust then throw a compiler error because we've created a situation where we can orphan part of "Hello world"?
> The original pointer &str does not own the "Hello world" variable but is a reference to it.
Correct.
> The new &mut T pointer takes ownership of the &str reference
&T/&mut T never take ownership. It is true that &mut T must be exclusive, so it's sort of like "temporary ownership", but the underlying T won't be destroyed when the reference goes out of scope.
> so the original specified (p,11) would be destroyed/overwritten when changed to (p,5).
The original &str will still live as long as it lives; we're creating a new one, and changing the &mut to point to it, not overwriting the existing one.
> The &mut T cannot edit the underlying string because it the reference it owns is a nonmutable reference. Even if the underlying string, "Hello world" was a mutable str variable, then &mut T could not access it since it was provided and immutable reference &str as its type.
Correct.
> If we provided a mutable pointer to the &mut T, would the mutable pointer would take ownership of the "Hello world"? If so, would Rust then throw a compiler error because we've created a situation where we can orphan part of "Hello world"?
No, &mut T never takes ownership.
Hope that helps! Happy to answer more questions if you've got them.
To restrict in the manner that the person above described would require some kind of const parameter in the type, no? The type would need to be parameterized over the `&str` to ensure that slices could only be taken from that particular string.
I am not familiar with the in-memory representation of Slice, but conceptually at least, yes. We call &str a "string slice" and &[T] more generally a "slice".
Sorry, I wrote Slice instead of Span in the original comment... Slice is the method that returns a Span that is the equivalent of this rust concept as far as I can tell.
At some point in the future I’ll need to delve in rust, it’s quite fascinating, but sadly I don’t have much time nowadays :(
Yeah I do that in a command line interface module for some firmware I wrote. No heap, very limited memory, solution string functions that understand the concept of white space delimited tokens. You just walk the pointer down the input string without modifying it.
For those of you not well-versed in Rust, this is a mutable pointer to an immutable string. This means that you can change the part of the string you’re pointing at, but you can’t change the underlying string itself.