for*_*emo 4 compiler-errors lifetime rust
我是Rust的新手,我发现很难理解整个所有权/借用概念....甚至在阅读了所有官方指南之后.
为什么以下代码编译没有任何问题?
use std::io;
fn main() {
let mut input = io::stdin();
let mut lock = input.lock();
let mut lines_iter = lock.lines();
for line in lines_iter {
let ok = line.ok();
let unwrap = ok.unwrap();
let slice = unwrap.as_slice();
println!("{}", slice);
}
}
Run Code Online (Sandbox Code Playgroud)
......但这不是吗?
use std::io;
fn main() {
let mut lines_iter = io::stdin().lock().lines();
for line in lines_iter {
let slice = line.ok().unwrap().as_slice();
println!("{}", slice);
}
}
Run Code Online (Sandbox Code Playgroud)
从我天真的角度来看,两个代码示例完全相同.唯一的区别是第一个使用一些中间变量,而第二个是链接函数调用.
在编译第二个时,它会对我大吼大叫
- error: borrowed value does not live long enough
- note: reference must be valid for the block at
- note:...but borrowed value is only valid for the statement
- help: consider using a `let` binding to increase its lifetime
Run Code Online (Sandbox Code Playgroud)
但说实话,我不知道编译器试图告诉我什么.我所理解的是,我有一个终身问题.但为什么?
两个代码示例之间有什么区别?为什么以及如何影响寿命?
定义中间变量可延长中间值的生命周期.临时值(例如io::stdin()和io::stdin().lock()in io::stdin().lock().lines())在语句结束时不再存在,除非它们被移动(情况就是这样io::stdin().lock()).
在let mut lines_iter = io::stdin().lock().lines();:
io::stdin() 返回一个新的 Stdin.lock()返回一个新的StdinLock<'a>(引用Stdin;你没有<'a>在文档中看到,因为生命周期在源中被删除).lines()返回一个新的Lines<StdinLock<'a>>(取得锁的所有权).返回类型的生命周期参数.lock()表示锁从Stdin对象借用.当你借用某个物体时,该物体必须至少与借用一样长.但是,你试图让一个变量持续到函数结束,但是从一个将在语句末尾删除的对象借用(因为它io::stdin()是一个临时值).
历史记录:当这个问题最初被问到时,.lines()会从锁中借用.现在,.lines()取代锁的所有权.这意味着现在只io::stdin()需要绑定到变量; 它不再需要绑定结果input.lock().