1.25.0-ночью (2018-01-11 73ac5d6)
следующая функция:
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
) не сохраняет никаких ссылок на первоисточник. На самом деле, назначение того же результата привязке перед возвратом работает нормально (Детская площадка).
fn bar() -> usize {
let stdin = stdin();
let stdinlock = stdin.lock();
let r = stdinlock
.lines()
.count();
r
}
Это говорит о том, что немедленное возвращение «использованной блокировки» привело к тому, что блокировка попыталась жить дольше, чем заблокированный контент, во многом необычным образом. Все ссылки, на которые я смотрел, обычно указывают, что порядок объявления имеет значение, но не то, как возвращаемые объекты могут влиять на порядок, в котором они выпущены.
Так почему же первая функция отклонена компилятором? Почему блокировка сохраняется дольше, чем ожидалось?