这没有多大意义,因为无论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();
}
}
此代码会产生错误:
error[E0499]: cannot borrow `self.value` as mutable more than once at a time
--> src/lib.rs:11:16
|
6 | fn get(&mut self) -> Option<&mut i32> {
| - let's call the lifetime of this reference `'1`
7 | if let Some(val) = &mut self.value {
| --------------- first mutable borrow occurs here
8 | return Some(val);
| --------- returning this value requires that `self.value` is borrowed for `'1`
...
11 | return self.value.as_mut();
| ^^^^^^^^^^ second mutable borrow occurs here
我不明白为什么当第一个借项超出范围而又没有第二个借项发生时,这又是第二个可变借项。
val
变量不在if let
的范围内,那么这又是第二次借用吗?第一次借用应该已经释放。
完全可以肯定的是,我甚至将if let
用另一个方块包围了:
{
if let Some(val) = &mut self.value {
return Some(val);
}
}
return self.value.as_mut();
这产生了相同的错误。这是怎么回事?
答案 0 :(得分:7)
'a
的生命周期包含整个函数体,因为返回值需要借用self
。因此,第一次借用的范围超出了if表达式,并扩展到整个函数体。
非词法生存时间旨在通过将第一次借用的范围减小为仅包括if表达式来解决此issue。您可以通过将借入的值移动到局部变量(playground)中来看到这一点:
fn get(&mut self) -> Option<&mut i32> {
let value = &mut self.value;
if let Some(val) = value {
return Some(val);
}
return value.as_mut();
}
但是,对有条件返回值的支持是removed,因为它花费了太多的编译时间。此功能仍在使用中,可以通过-Zpolonius
标志启用:
RUSTFLAGS="-Zpolonius" cargo build +nightly
使用它,原始代码可以很好地编译。