以下代码无法编译
use std::io::{BufRead, BufReader};
use std::net::{TcpListener};
fn main() {
let listener = TcpListener::bind(format!("0.0.0.0:{}", 7007)).unwrap();
for stream in listener.incoming() {
let mut stream = stream.unwrap();
let mut buf_reader = BufReader::new(&mut stream);
let buf = buf_reader.fill_buf().unwrap();
buf_reader.consume(buf.len())
}
}
字符串
错误:
error[E0499]: cannot borrow `buf_reader` as mutable more than once at a time
--> src/main.rs:10:9
|
9 | let buf = buf_reader.fill_buf().unwrap();
| --------------------- first mutable borrow occurs here
10 | buf_reader.consume(buf.len())
| ^^^^^^^^^^^^^^^^^^^---------^
| | |
| | first borrow later used here
| second mutable borrow occurs here
型
我不明白这与文档示例中使用的代码有何不同
1条答案
按热度按时间nr7wwzry1#
fill_buf
方法接受一个mutable reference to the struct,所以这是一个可变的借用。consume
方法 * 也 * 接受一个&mut self
,和fill_buf
一样,所以如果编译器认为你仍然坚持第一个,那就不行了。在Rust中,可变引用是完全排他的:你不能对同一块内存持有多个可变引用。
您的代码和文档中的示例之间的区别在于,在文档示例中,编译器在您获取长度时就知道您已经完成了
buf
(读取器的第一个可变借用),因此它可以释放“锁”,并为您调用.consume
做好准备。尽管 * 逻辑上 * 这两者应该是等价的,但请记住,Rust编译器正在做所有这些(非常复杂的)静态分析,以便为您管理内存资源并保证一定程度的线程安全性,而不必使用 * 实际 * 锁,因此它在某种程度上受到源代码的 * 文本 * 的限制,而不是其逻辑运行时语义。
只需按照Jume-fh在注解中的建议执行,并将调用拆分为
.len
:字符串