当返回使用StdinLock的结果时,为什么要保留stdin的借用?
问题描述:
鉴于以下功能:当返回使用StdinLock的结果时,为什么要保留stdin的借用?
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
}
这表明,返回一个“消费锁”立即导致了锁试图活得比锁定的内容,多以不寻常的方式。我研究过的所有参考文献通常都指出声明的顺序很重要,但并不知道返回的对象如何影响它们被释放的顺序。
那为什么前面的函数被编译器拒绝?为什么锁看似比预期更长久?
答
这似乎是编译器中的一个错误。你可以让编译器高兴通过使用一个明确的return
声明:
use std::io::{stdin, BufRead};
fn foo() -> usize {
let stdin = stdin();
let stdinlock = stdin.lock();
return stdinlock
.lines()
.count();
}
fn main() {}
正如在评论中提到的,也有与此相关的多种锈病问题:
哦。有趣! –
@MatthieuM。原因似乎是'MutexGuard'的魔法。我仅仅根据类型做了一个简单的复制。见[这里](https://gist.github.com/peterjoel/f6a1e1ec29da1ee73994820f742cdb7d#file-stlocklock_problem-rs)。在破解的版本中,我使用'std'中的'MutexGuard'。在工作的版本中,我复制粘贴相同的代码而不是使用'std'。 –
有没有人提出过错误报告? – Veedrac