rust 如何使用BufReader的fill_buff并使用TcpStream进行消费

iswrvxsc  于 12个月前  发布在  其他
关注(0)|答案(1)|浏览(98)

以下代码无法编译

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


我不明白这与文档示例中使用的代码有何不同

nr7wwzry

nr7wwzry1#

fill_buf方法接受一个mutable reference to the struct,所以这是一个可变的借用。consume方法 * 也 * 接受一个&mut self,和fill_buf一样,所以如果编译器认为你仍然坚持第一个,那就不行了。
在Rust中,可变引用是完全排他的:你不能对同一块内存持有多个可变引用。
您的代码和文档中的示例之间的区别在于,在文档示例中,编译器在您获取长度时就知道您已经完成了buf(读取器的第一个可变借用),因此它可以释放“锁”,并为您调用.consume做好准备。
尽管 * 逻辑上 * 这两者应该是等价的,但请记住,Rust编译器正在做所有这些(非常复杂的)静态分析,以便为您管理内存资源并保证一定程度的线程安全性,而不必使用 * 实际 * 锁,因此它在某种程度上受到源代码的 * 文本 * 的限制,而不是其逻辑运行时语义。
只需按照Jume-fh在注解中的建议执行,并将调用拆分为.len

let length = buf.len(); // compiler can now drop first mutable borrow because we don't use buf again
buf_reader.consume(length); // second &mut is now exclusive

字符串

相关问题