use std::fs::File;
use std::io::prelude::*;
use std::io::BufReader;
fn main() {
let f = File::open("test.txt").expect("Can't open");
let mut b = BufReader::new(f);
let v = b.fill_buf().unwrap();
println!("v: {:?}", v);
b.consume(v.len());
}
将不会编译,错误为
error[E0499]: cannot borrow `b` as mutable more than once at a time
--> src/main.rs:10:5
|
7 | let v = b.fill_buf().unwrap();
| ------------ first mutable borrow occurs here
...
10 | b.consume(v.len());
| ^^^^^^^^^^-------^
| | |
| | first borrow later used here
| second mutable borrow occurs here
将最后几行更改为:
let len = v.len();
b.consume(len);
一切都好。
我不明白为什么第一个例子借用了两次,为什么在变量中存储长度并将该变量传递给b.consume()
是可以的--有人能解释一下为什么2. variant是可以的,而第一个不是?
1条答案
按热度按时间scyqe7ek1#
当你遇到这类问题时,把事情简单化会有帮助。你可能知道,方法语法是关联函数调用的语法糖:
参数表达式通常是从左到右求值的,所以我们尝试在释放
v
中的引用之前,获取一个新的对b
的可变引用。在某些情况下,编译器可以识别并自动避免这个问题,但这似乎不是其中之一。你可能会问:“为什么它说第二个可变引用?
v
是一个不可变引用!”当你调用b.fill_buf()
时,v
中的引用的生存期与可变引用的生存期相关联。所以编译器认为对b
的可变引用必须保持有效,直到v
被释放。这个修复之所以有效,是因为它翻转了参数的顺序,首先计算
v.len()
,然后释放第一个引用。