2017-01-22 70 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

相關問題