为什么我不能从枚举中可变地借用一个原语?

时间:2017-05-20 18:37:24

标签: enums rust borrow-checker

我希望能够获得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}}的其他内容 - 为什么可变借用(以及为什么只有它)失败并带有未装箱的原语?

2 个答案:

答案 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 TT 的不变性可能与有关,因为它导致&mut &'a mut T'a不变,因此&&'a T)情况更具限制性,即使在这种情况下 ,严格性也是不必要的。