为什么不能在可变字符串引用上调用可变方法但适用于 TcpStream
Why can't a mutable method be called on a mutable String reference but works for TcpStream
当我试图理解一个可变变量之间的区别时,它恰好是一个引用,例如let mut x: &i32
与可变引用,例如let x: &mut i32
,我发现这个差异我无法理解:
这有效,其中 by_ref
具有签名:fn by_ref(&mut self) -> &mut Self
(docs)
fn example(mut t: &TcpStream) {
t.by_ref();
}
但是以下 String
,使用具有相似签名的方法,reserve
:
pub fn reserve(&mut self, additional: usize)`
但是这样不行,错误是:
"cannot borrow *str
as mutable, as it is behind a &
reference"
fn example(mut str: &String) {
str.reserve(10);
}
有趣的是,这两个具有可变引用的示例有效,据我所知,这是使用可变方法的推荐方式:
fn example_stream(t: &mut TcpStream) {
t.by_ref();
}
fn example_string(str: &mut String) {
str.reserve(10);
}
那么 TcpStream
和 String
允许在一种情况下调用带有 &mut self
参数的方法而不是在另一种情况下调用的方法有什么不同?
您的 TcpStream
样本误导了您。
有impl Read for TcpStream
as you've linked to, but there is also impl Read for &TcpStream
。您实际上使用的是后者,它不需要对 TcpStream
的可变访问,只需要对 TcpStream
的 reference 的可变访问,即 t
.
这样做是因为 Read
特性使用可变方法来允许需要突变或独占访问权限的读者进行读取。然而 TcpStream
实际上不需要突变或独占访问来读取数据,因为它本质上只是服从系统调用。因此,TcpStream
可以更加灵活,并允许多个线程通过在其引用上实现 Read
从套接字 read/write。
另一方面,str.reserve()
调用没有这种奢侈,需要对 String
本身进行可变访问,因此 &String
是不够的。
当我试图理解一个可变变量之间的区别时,它恰好是一个引用,例如let mut x: &i32
与可变引用,例如let x: &mut i32
,我发现这个差异我无法理解:
这有效,其中 by_ref
具有签名:fn by_ref(&mut self) -> &mut Self
(docs)
fn example(mut t: &TcpStream) {
t.by_ref();
}
但是以下 String
,使用具有相似签名的方法,reserve
:
pub fn reserve(&mut self, additional: usize)`
但是这样不行,错误是:
"cannot borrow
*str
as mutable, as it is behind a&
reference"
fn example(mut str: &String) {
str.reserve(10);
}
有趣的是,这两个具有可变引用的示例有效,据我所知,这是使用可变方法的推荐方式:
fn example_stream(t: &mut TcpStream) {
t.by_ref();
}
fn example_string(str: &mut String) {
str.reserve(10);
}
那么 TcpStream
和 String
允许在一种情况下调用带有 &mut self
参数的方法而不是在另一种情况下调用的方法有什么不同?
您的 TcpStream
样本误导了您。
有impl Read for TcpStream
as you've linked to, but there is also impl Read for &TcpStream
。您实际上使用的是后者,它不需要对 TcpStream
的可变访问,只需要对 TcpStream
的 reference 的可变访问,即 t
.
这样做是因为 Read
特性使用可变方法来允许需要突变或独占访问权限的读者进行读取。然而 TcpStream
实际上不需要突变或独占访问来读取数据,因为它本质上只是服从系统调用。因此,TcpStream
可以更加灵活,并允许多个线程通过在其引用上实现 Read
从套接字 read/write。
另一方面,str.reserve()
调用没有这种奢侈,需要对 String
本身进行可变访问,因此 &String
是不够的。