Minimal reproducible example:
use std::io::{stdin, BufRead};
fn main() {
for line in stdin().lock().lines() {
println!("{}", line.unwrap())
}
}
error:
Compiling playground v0.0.1 (file:///playground)
error[E0597]: borrowed value does not live long enough
--> src/main.rs:4:17
|
4 | for line in stdin().lock().lines() {
| ^^^^^^^ temporary value does not live long enough
5 | println!("{}", line.unwrap())
6 | }
| - temporary value dropped here while still borrowed
|
= note: values in a scope are dropped in the opposite order they are created
= note: consider using a `let` binding to increase its lifetime
It works:
let stdin = stdin();
for line in stdin.lock().lines() { ... }
I see io::stdin()
returns Stdin
struct which is borrowed by lock
method returning StdinLock
which is borrowed by BufRead::lines()
returning iterator which will be destroyed at the end of for
loop.
We can see that
values in a scope are dropped in the opposite order they are created
therefore dropping order is: Iter
=> StdinLock
=> Stdin
thus when Stdin
gets dropped it's not borrowed anymore so there's no need to increase its lifetime with let
bound.
Am I wrong?
UPD
What happens: Why doesn't `io::stdin().lock().lines().count()` work? - #7 by jorendorff
What to do?: create some temporary let
bindings to get nested lifetimes.