考虑下面的函数:
use std::io::{BufRead, stdin};
fn foo() -> usize {
let stdin = stdin();
let stdinlock = stdin.lock();
stdinlock
.lines()
.count()
}
使用以下错误无法通过编译:
error: `stdin` does not live long enough
--> src/main.rs:12:1
|
7 | let stdinlock = stdin.lock();
| ----- borrow occurs here
...
11 | }
| ^ `stdin` dropped here while still borrowed
|
= note: values in a scope are dropped in the opposite order they are created
我觉得这很令人惊讶,因为通过锁(通过lines
)消耗的结果并不保留对原始来源的任何引用。实际上,在返回之前将相同的结果分配给绑定变量也可以正常工作(Playground)。
fn bar() -> usize {
let stdin = stdin();
let stdinlock = stdin.lock();
let r = stdinlock
.lines()
.count();
r
}
这表明立即返回一个“已消耗的锁”导致锁试图以一种不寻常的方式比锁定的内容更长时间地存在。我查阅的所有参考资料通常指出声明顺序很重要,但没有说明返回的对象如何影响它们释放的顺序。
那么为什么编译器会拒绝前面的函数呢?为什么锁似乎被保留的时间比预期要长?
MutexGuard
周围有一些神奇的东西。我根据类型做了一个过度简化的复制,点击这里。在崩溃的版本中,我使用了来自std
的MutexGuard
。在正常工作的版本中,我复制粘贴了相同的代码而不是使用std
。 - Peter Hall