2017-01-22 39 views
3

添加时,对i32的不可变和可变引用有什么区别?

fn plus_one(x: &i32) -> i32 { 
    x + 1 
} 

fn plus_one_star(x: &i32) -> i32 { 
    *x + 1 
} 

fn plus_one_mut(x: &mut i32) -> i32 { 
    x + 1 
} 

fn plus_one_mut_star(x: &mut i32) -> i32 { 
    *x + 1 
} 

fn main() { 
    let a: i32 = 5; 
    let mut b: i32 = 5; 

    println!("{:?}", plus_one(&a)); 
    println!("{:?}", plus_one_star(&a)); 
    println!("{:?}", plus_one_mut(&mut b)); 
    println!("{:?}", plus_one_mut_star(&mut b)); 
    // I expect all to print '6' as I never actually mutate b 
} 

第三个功能,plus_one_mut,失败,编译:error[E0369]: binary operation `+` cannot be applied to type '&mut i32'

为什么与可变引用这个函数编译失败?

回答

4

随着错误消息指出:

二元运算+不能应用于键入“& MUT 123-132”

这是因为它没有实现。回顾the documentation for i32,你会看到的Add这些实现:

  • impl Add<i32> for i32
  • impl<'a> Add<i32> for &'a i32
  • impl<'a> Add<&'a i32> for i32
  • impl<'a, 'b> Add<&'a i32> for &'b i32

您需要取消引用&mut i32i32,里面确实有一个Add执行。

为什么没有这个实现?我不确定。也许你可以向Rust提交一个PR来添加它......就我个人而言,我已经记不起需要它了。通常如果你有一个&mut T这是因为你想要来更新它,所以你会有类似*foo += 1

+1

奇怪的是'x.add(1)'适用于所有情况,但是...在这种情况下,可能会有强制手段? –

+0

@PaoloFalabella我不确定何时*胁迫*是正确的;但是,我会假设[自动解除引用](http://stackoverflow.com/q/28519997/155423)即将发挥作用。 – Shepmaster

+0

因此,在这种情况下,'&T'的行为就像'T'。一般来说,我应该在使用它们之前解除引用所有不可变的引用吗?或者为'&T'实现大多数'T'方法是非常常见的? – turbulencetoo

相关问题