我希望能够获得usize
枚举Bar
中包含的Foo
的引用(包括不可变和可变):
use Foo::*;
#[derive(Debug, PartialEq, Clone)]
pub enum Foo {
Bar(usize)
}
impl Foo {
/* this works */
fn get_bar_ref(&self) -> &usize {
match *self {
Bar(ref n) => &n
}
}
/* this doesn't */
fn get_bar_ref_mut(&mut self) -> &mut usize {
match *self {
Bar(ref mut n) => &mut n
}
}
}
但我无法获得可变引用,因为:
n
活得不够长
我能够提供类似函数的两种变体,访问Foo
Box
的{{1}}的其他内容 - 为什么可变借用(以及为什么只有它)失败并带有未装箱的原语?
答案 0 :(得分:7)
您需要将Bar(ref mut n) => &mut n
替换为Bar(ref mut n) => n
。
在ref mut n
中使用Bar(ref mut n)
时,会创建一个可变对象
引用Bar
中的数据,因此n
的类型为&mut usize
。
然后,您尝试返回&mut n
类型的&mut &mut u32
。
此部分很可能不正确。
现在deref coercion开始了 并将
&mut n
转换为&mut *n
,创建临时值*n
usize
类型,其生存时间不够长。
答案 1 :(得分:7)
这些示例显示了示例问题:
fn implicit_reborrow<T>(x: &mut T) -> &mut T {
x
}
fn explicit_reborrow<T>(x: &mut T) -> &mut T {
&mut *x
}
fn implicit_reborrow_bad<T>(x: &mut T) -> &mut T {
&mut x
}
fn explicit_reborrow_bad<T>(x: &mut T) -> &mut T {
&mut **&mut x
}
explicit_
版本显示了编译器通过deref coercions推断出的内容
_bad
版本的错误方式完全相同,而其他两个编译错误。
这可能是一个错误,也可能是对编译器当前实现生命周期的限制。 &mut T
对T
的不变性可能与有关,因为它导致&mut &'a mut T
对'a
不变,因此&&'a T)情况更具限制性,即使在这种情况下 ,严格性也是不必要的。