Rust 如果让借回来后留下来,即使带#![专题(nll)]

Rust 如果让借回来后留下来,即使带#![专题(nll)],rust,borrow-checker,Rust,Borrow Checker,我正在处理一个大文件,但这是一个引起相同问题的小玩具示例。对不起,如果这个例子本身没有意义 #![feature(nll)] struct S(i32); impl S { fn foo(&mut self) -> Option<&i32> { if let Some(val) = self.bar() { return Some(val); } let y = &mut

我正在处理一个大文件,但这是一个引起相同问题的小玩具示例。对不起,如果这个例子本身没有意义

#![feature(nll)]
struct S(i32);

impl S {
    fn foo(&mut self) -> Option<&i32> {
        if let Some(val) = self.bar() {
            return Some(val);
        }
        let y = &mut self.0;
        None
    }

    fn bar(&mut self) -> Option<&i32> {
        None
    }
}

fn main() {
    S(0).foo();
}

让我们在这里详细了解生命周期。函数
foo()

fn foo<'a>(&'a mut self) -> Option<&'a i32>
创建一个生存期为某个生存期的
self
借用
'b
,并且返回的引用
val
也具有此生存期
'b
。由于您随后返回
Some(val)
,因此
'b
的生存期必须超过
self
参数的
'a
的生存期,这肯定比
foo()
的运行期长。这意味着您以后在
foo()
中的任何时候都不能再借用
self

我认为本例中令人惊讶的是,即使
bar()
返回
None
,也会借用
self
。直觉上,我们觉得在这种情况下不会返回任何引用,所以我们不需要借用。但是,生锈寿命由类型检查器检查,类型检查器不理解类型不同值的含义。
bar()
返回的值具有类型
选项();
}

现在我们调用了两次
bar()
,每个调用都有不同的生存期。现在只有生存期
'c
需要比
'a
更长,但是生存期
'b
只需要足够长的时间来调用结果上的
is_some()
。生命周期
'c
的借用仅在执行分支时发生,不会发生冲突。

但保留引用的分支会返回!否则,为什么简单if语句的情况有效?它使用相同的借词。@Mohammed只有一个生存期
'b
,借词检查器试图为其找到合适的值。if
的每个分支没有两个不同的生存期。我将在回答为什么另一个版本有效的问题时添加一条注释。有没有安全的方法可以不借用两次就重写它?正如我所看到的,代码在逻辑上是安全的,如果我错了,请纠正我。NLL不会帮助您——它们会帮助您,当NLL的下一次迭代启用时。有关更多信息,请参阅链接副本。@Mohammed我认为代码是安全的。我想不出一个简单的解决方案——我想我需要了解更多的上下文,才能提出如何重新设计的建议。
fn foo<'a>(&'a mut self) -> Option<&'a i32>
if let Some(val) = self.bar() {
if self.bar<'b>().is_some() {
    return self.bar<'c>();                                                                                      
}