编译器错误 – 链接函数调用与使用中间变量

我是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);
    }
}

……但这不是吗?

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);
    }
}

从我天真的角度来看,两个代码示例完全相同.唯一的区别是第一个使用一些中间变量,而第二个是链接函数调用.

在编译第二个时,它会对我大吼大叫

- 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

但说实话,我不知道编译器试图告诉我什么.
我所理解的是,我有一个终身问题.但为什么?

两个代码示例之间有什么区别?为什么以及如何影响寿命?

定义中间变量可延长中间值的生命周期. io :: stdin().lock().lines())中的临时值(例如io :: stdin()和io :: stdin().lock()不再存在于语句的末尾,除非它们存在’被移动(这是io :: stdin().lock()的情况).

在let mut lines_iter = io :: stdin().lock().lines();:

> io::stdin()返回一个新的Stdin
> .lock()返回一个新的StdinLock<'a> (引用了Stdin;你没有在文档中看到<'a>因为源中的生命周期是elided)
> .lines()返回新行< StdinLock<'a>> (取得锁的所有权).

返回类型.lock()上的lifetime参数表示锁从Stdin对象借用.当你借用某个物体时,该物体必须至少与借用一样长.但是,你试图让一个变量持续到函数结束,但是从一个将在语句末尾删除的对象借用(因为io :: stdin()是一个临时值).

历史记录:当最初询问这个问题时,.lines()会从锁中借用.现在,.lines()取代了锁的所有权.这意味着现在只需要将io :: stdin()绑定到变量;不再需要绑定input.lock()的结果.

相关文章
相关标签/搜索