Учитывая следующую функцию:
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
}
Это говорит о том, что немедленное возвращение "потребляемой блокировки" привело к тому, что блокировка, пытающаяся жить дольше заблокированного контента, необычно. Все ссылки, на которые я смотрел, обычно указывают на то, что порядок декларирования имеет значение, но не как возвращаемые объекты могут влиять на порядок, в котором они выпущены.
Итак, почему первая функция отвергается компилятором? Почему блокировка кажется сохраненной дольше, чем ожидалось?