0

I have a function that takes the mutable reference of the string and appends some text.

fn append_str(s: &mut String) {
    s.push_str(" hi");
}

Suppose I have a string.

let mut s: String = "hi".to_string();

If I create the mutable reference to s and pass it to append_str, it compiles without a problem.

let mut ss = &mut s;

append_str(&mut ss);

However, if I expliclty define ss with &mut String, it does not compile.

let ss: &mut String = &mut s;
append_str(&mut ss);

it shows following compiler error.

   |
80 |     let ss: &mut String = &mut s;
   |         -- help: consider changing this to be mutable: `mut ss`
81 |     append_str(&mut ss);
   |                ^^^^^^^ cannot borrow as mutable

One thing funny is that if I dereference it, then it works.

let ss: &mut String = &mut s;
append_str(&mut *ss); // OK

What is the reason that we have to explicitly dereference in this case?

One more question: Why do we have to specify mut to the reference if we want to pass it to the function?

let ss = &mut s;
append_str(&mut ss); // ERROR

1 Answer 1

4

ss is a reference already, so &mut ss gives you (mutable) reference to (mutable) reference; if you have ss, you should call append_str with it directly: append_str(ss).

It is only when you incorrectly take a mutable reference to ss, you need to declare it as mut ss. The normal use case for something like that is to pass it to a function that actually accepts x: &mut &mut String and uses something like *x = &mut some_other_string to make ss refer to a different reference to string. In your case the "fixed" code with mut compiles because the compiler automatically dereferences the double-reference for you.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.