2017-04-12 32 views
4

如何理解以下代碼段?我是Rust的新手,但在C/Haskell和一點C++方面有背景知識。我能找到的唯一參考是deref coercions瞭解(自動?)添加參考和數字值時的參考/強制

fn main() { 
    let xs: [u32; 4] = [0, 1, 2, 3]; 
    let mut i: u32 = 0; 
    for x in xs.iter() { 
     if i > *x {  // It looks x is an iterator. Understood.    
      i = i + x; // no error. (coerced) 
         //Quote: "Rust will do this as many times 
         //  as possible until the types match." 
      i = i + *x; // no error (explicit deref) 
      i += x;  // error about u32/&u32 mismatch. Why the magic failed? 
      i += *x; // no error (explicit deref) 
     } 
    } 
    println!("{}", i); 
} 

回答

8

沒有自動DEREF或脅迫這裏,i + x工作僅僅是因爲u32同時實現了Add<u32>Add<&u32>。如果你檢查the docs for u32,你會發現以下四個特點impls:

impl Add<u32> for u32 
impl<'a> Add<u32> for &'a u32 
impl<'a> Add<&'a u32> for u32 
impl<'a, 'b> Add<&'a u32> for &'b u32 

u32只實現AddAssign<u32>但不AddAssign<&u32>this is a bugwill be fixed in 1.18 or 1.19修復它causes regression這意味着這可能IMPL需要等待鏽2.0) ,所以i += x是一個錯誤。

impl AddAssign<u32> for u32 
//impl<'a> AddAssign<&'a u32> for u32 <-- is missing. 

爲什麼自動取消引用不會發生呢? - 只有當它是接收方時纔會發生Auto-deref,即方法調用foo.bar()中的「self」。 x不是「自我」的說法,+不是方法調用。所以這裏沒有auto-deref。詳情請參閱What are Rust's exact auto-dereferencing rules?

+0

感謝您的回答和參考。 – Nybble

+0

我認爲'a + b'是'a.add(b)'的糖(來自'std :: ops :: Add'的'add')。如果是這種情況,'a + b' *將是'a'自身的方法調用,並且自動解引用將適用於操作符。我想知道這種方法是否有缺點,因爲Rust選擇不定義這樣的運算符。 – user4815162342

+0

@ user4815162342有自動解除引用,但它僅適用於'a' – torkleyy