当我试图理解可变变量(恰好是引用)let mut x: &i32与可变引用(例如)之间的差异时let x: &mut i32,我发现了我无法理解的差异:
这有效,其中by_ref有签名fn by_ref(&mut self) -> &mut Self:(文档)
fn example(mut t: &TcpStream) {
t.by_ref();
}
Run Code Online (Sandbox Code Playgroud)
但下面的String,使用具有类似签名的方法reserve:
pub fn reserve(&mut self, additional: usize)
Run Code Online (Sandbox Code Playgroud)
但这不起作用,错误是:
“不能借用
*str可变的,因为它位于&引用后面”
pub fn reserve(&mut self, additional: usize)
Run Code Online (Sandbox Code Playgroud)
有趣的是,这两个具有可变引用的示例有效,并且据我所知,是使用可变方法的推荐方法:
fn example(mut str: &String) {
str.reserve(10);
}
Run Code Online (Sandbox Code Playgroud)
TcpStream那么 a和 a之间有什么不同String,允许&mut self在一种情况下调用带有参数的方法,而在另一种情况下则不允许呢?
你的TcpStream样本误导了你。
有如impl Read for TcpStream您链接到的那样,但也有impl Read for &TcpStream. 您实际上使用的是后者,它不需要对 the 进行可变访问,只需要对 the 的引用TcpStream进行可变访问,即。TcpStreamt
这样做是因为该Read特征使用可变方法来允许需要突变或独占访问的读者进行读取。然而,TcpStream实际上不需要突变或独占访问来读取数据,因为它本质上只是遵循系统调用。因此,通过实现其引用,TcpStream可以更加灵活并允许多个线程从套接字读取/写入。Read
另一方面,调用str.reserve()则没有这种奢侈,并且需要对其自身进行可变访问String,因此 a&String是不够的。