Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Why can't a mutable method be called on a mutable String reference but works for TcpStream

As I was trying to understand the differences between a mutable variable, which happens to be a reference, e.g. let mut x: &i32 vs mutable references, e.g. let x: &mut i32, I found this difference I can’t understand:

This works, where by_ref has the signature: fn by_ref(&mut self) -> &mut Self (docs)

fn example(mut t: &TcpStream) {
    t.by_ref();
}

But the following with String, using a method with a similar looking signature, reserve:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

pub fn reserve(&mut self, additional: usize)`

But this does not work, the error is:

"cannot borrow *str as mutable, as it is behind a & reference"

fn example(mut str: &String) {
    str.reserve(10);
}

Interesting to note that these two examples with mutable references work, and are, as far I know, the recommended way to use mutable methods:

fn example_stream(t: &mut TcpStream) {
    t.by_ref();
}

fn example_string(str: &mut String) {
    str.reserve(10);
}

So what is different between a TcpStream and a String that allows methods with a &mut self argument to be called in one case and not in the other?

>Solution :

Your TcpStream sample is misleading you.

There is impl Read for TcpStream as you’ve linked to, but there is also impl Read for &TcpStream. You are actually using the latter which does not need mutable access to the TcpStream, only mutable access to the reference to the TcpStream, which is t.

This is done because the Read trait uses mutable methods to allow readers that need mutation or exclusive access to read. However TcpStream actually doesn’t need mutation or exclusive access to read data since it essentially just defers to a syscall. Because of this, TcpStream can be more flexible and allow multiple threads to read/write from a socket by implementing Read on its reference.

The str.reserve() call, on the otherhand, does not have this luxury and requires mutable access to the String itself, and thus a &String is not enough.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading