Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

A bit problem about Rust's function parameter and ownership [duplicate]

Tags:

rust

ownership

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?

like image 634
bellemere Avatar asked Nov 07 '22 01:11

bellemere


1 Answers

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.

like image 62
bellemere Avatar answered Nov 11 '22 07:11

bellemere