here's my problem:
fn main() {
let mut s = String::from("hello");
let s1 = &mut s;
let s2 = s1;
*s2 = String::from("world1");
*s1 = String::from("world2");
println!("{:?}", s);
}
it will result in a compile error because s1 has type &mut String
which doesn't implement the Copy
trait.
But if I change the code as below:
fn c(s: &mut String) -> &mut String {
s
}
fn main() {
let mut s = String::from("hello");
let s1 = &mut s;
let s2 = c(s1);
*s2 = String::from("world1");
*s1 = String::from("world2");
println!("{:?}", s);
}
it will compile without any error message.
I know when a reference passed to a function, it means the reference borrows
the value insteading of owning it.
But in the situation above, it seems like when s1 was passed to fn c
and returned immediatelly, s2 borrowed
s1 so s1 couldn't be derefed until s2 was out of it's lifetime scope.
So what happened when s1 was passed into the fn c
?
From @Denys Séguret's hint, I guess when s1 was passed to fn C
, Rust core compiled the parameter s1
to something like &mut *s1
, so there was an immutable borrow of s1.
That's why if we put
*s2 = String::from("world1");
behind
*s1 = String::from("world2");
Rust would tell us:
assignment to borrowed `*s1`
And when s2 goes out of it's lifetime scope, there is no borrow of s1 anymore, so s1 can be derefed again.
But I'm not quite sure whether it's a right explanation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With