第二次可变借款错误,只有一次可变借款

Joh*_*yer 2 rust

这没有多大意义,因为无论返回,它都会返回相同的东西if let,但这是我遇到的问题的简要示例:

struct Data {
    value: Option<i32>,
}

impl Data {
    fn get(&mut self) -> Option<&mut i32> {
        if let Some(val) = &mut self.value {
            return Some(val);
        }

        return self.value.as_mut();
    }
}
Run Code Online (Sandbox Code Playgroud)

此代码产生错误:

struct Data {
    value: Option<i32>,
}

impl Data {
    fn get(&mut self) -> Option<&mut i32> {
        if let Some(val) = &mut self.value {
            return Some(val);
        }

        return self.value.as_mut();
    }
}
Run Code Online (Sandbox Code Playgroud)

我不明白为什么当第一个借项超出范围而又没有第二个借项发生时,这又是第二个可变借项。

val变量在以后的范围if let,所以这是一个怎样次贷?第一次借用应该已经释放。

完全可以肯定的是,我什至if let用另一个方块包围了:

{
    if let Some(val) = &mut self.value {
        return Some(val);
    }
}

return self.value.as_mut();
Run Code Online (Sandbox Code Playgroud)

这产生了相同的错误。这里发生了什么?

小智 7

'a因为返回值需要借用,所以生命周期包含整个函数体self。因此,第一次借用的范围超出了if表达式,并扩展到整个函数体。

非词法生存时间旨在通过将第一次借用的范围缩小为仅包含if表达式来解决此问题。您可以通过将借入的值移动到局部变量(游乐场)中来看到此效果:

fn get(&mut self) -> Option<&mut i32> {
    let value = &mut self.value;
    if let Some(val) = value {
        return Some(val);
    }
    return value.as_mut();
}
Run Code Online (Sandbox Code Playgroud)

但是,取消了对有条件返回值的支持,因为这花费了太多的编译时间。此功能仍在使用中,可以通过以下-Zpolonius标志启用:
RUSTFLAGS="-Zpolonius" cargo build +nightly

这样,原始代码可以很好地编译。