Когда возвращался результат потребления 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
) не содержит ссылок на исходный источник. Фактически, присвоение того же результата привязке перед возвратом работает просто отлично (Игровая площадка).
fn bar() -> usize {
let stdin = stdin();
let stdinlock = stdin.lock();
let r = stdinlock
.lines()
.count();
r
}
Это говорит о том, что немедленное возвращение "потребляемой блокировки" привело к тому, что блокировка, пытающаяся жить дольше заблокированного контента, необычно. Все ссылки, на которые я смотрел, обычно указывают на то, что порядок декларирования имеет значение, но не как возвращаемые объекты могут влиять на порядок, в котором они выпущены.
Итак, почему первая функция отвергается компилятором? Почему блокировка кажется сохраненной дольше, чем ожидалось?
Ответы
Ответ 1
Кажется, это ошибка в компиляторе. Вы можете сделать компилятор счастливым, используя явную инструкцию return
:
use std::io::{stdin, BufRead};
fn foo() -> usize {
let stdin = stdin();
let stdinlock = stdin.lock();
return stdinlock
.lines()
.count();
}
fn main() {}
игровая площадка
Как упоминалось в комментариях, существует несколько проблем Rust, связанных с этим:
Ответ 2
Я не могу ответить на вопрос о том, почему ваш вопрос, но могу утверждать, что текущая реализация несексных времен жизни 1 позволяет скомпилировать исходный код:
#![feature(nll)]
use std::io::{BufRead, stdin};
fn foo() -> usize {
let stdin = stdin();
let stdinlock = stdin.lock();
stdinlock
.lines()
.count()
}
Игровая площадка
1 1.25.0-nightly (2018-01-11 73ac5d6)