Когда возвращался результат потребления 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 } 

Это говорит о том, что немедленное возrotation «потребляемой блокировки» привело к тому, что блокировка попыталась жить дольше, чем заблокированный контент, что необычно. Все ссылки, на которые я смотрел, обычно указывают на то, что порядок декларирования имеет значение, но не то, как возвращенные объекты могут повлиять на порядок их выпуска.

Итак, почему первая функция отвергается компилятором? Почему замок, казалось бы, сохранился дольше, чем ожидалось?

Кажется, это ошибка в компиляторе. Вы можете сделать компилятор счастливым, используя явный оператор return :

 use std::io::{stdin, BufRead}; fn foo() -> usize { let stdin = stdin(); let stdinlock = stdin.lock(); return stdinlock .lines() .count(); } fn main() {} 

детская площадка

Как упоминалось в комментариях, существует несколько проблем Rust, связанных с этим:

  • 37407
  • 21114

Я не могу ответить на вопрос о том, почему ваш вопрос, но могу утверждать, что текущая реализация несекснических времен жизни позволяет скомпилировать исходный код:

 #![feature(nll)] use std::io::{BufRead, stdin}; fn foo() -> usize { let stdin = stdin(); let stdinlock = stdin.lock(); stdinlock .lines() .count() } 

Детская площадка

1 1,25,0-ночь (2018-01-11 73ac5d6)

Давайте будем гением компьютера.