2016-05-17 108 views
1

下面的代碼給出錯誤「無法移出借用內容」。我知道這裏有很多關於這方面的問題。我認爲每個使用Rust的人都會發現自己在某個地方,試圖弄清楚所有權究竟發生了什麼。我想我知道這裏發生了什麼,以及如何解決它,我只是不知道如何在這個特定情況下使用參考。如果有更習慣的方式來完成我所嘗試的,請在評論中告訴我。參考enum中的參數

我可以看到我想要擁有所有權,但我不確定如何使用參考。

讓我們看一個有點小例子:

/* I define two shape structs. The main point here is that they 
are not default copyable, unlike most primitive types */ 

struct Circle { 
    center_x: f64, 
    center_y: f64, 
    r: f64, 
} 

struct Square { 
    center_x: f64, 
    center_y: f64, 
    length: f64, 
} 

/* this enum will be a container for shapes because we don't know 
    which shape we might need. */ 

enum Shape { 
    // these are scoped differently, so it's okay. 
    Circle(Circle), 
    Square(Square), 
} 

/* I'm making cookies, each cookie has a shape */ 
struct Cookie { 
    shape: Shape, 
} 

/* All of the above was setup, here is where we find errors */ 

impl Cookie { 

    /* checks if two cookies have the same radius. squares -> false */ 

    fn has_same_radius(&self, other_cookie: &Cookie) -> bool { 
    // fn has_same_radius(self, other_cookie: Cookie) -> bool { 

    /* swapping the above two lines will remedy the error, 
     but I don't want this function to take ownership of either */ 

     match self.shape { 

      /* As soon as I declare c1, I'm taking ownership of self.shape 
       and therefore self as well. This is in spite of the fact 
       that I never plan to alter anything. 
       How can I simply use a reference to c1> */ 

      Shape::Circle(c1) => match other_cookie.shape { 

       /* same thing here with c2 */ 
       Shape::Circle(c2) => { 
        if c2.r == c1.r { 
         return true; 
        } 
       } 
       Shape::Square(_) => return false, 

      }, 
      Shape::Square(_) => return false, 
     } 
     return false; 

    } 

} 

當我在Shape枚舉匹配,我只想引用封裝在Shape參數,但因爲我沒有使用一個參考,我想獲取整個Cookie結構的所有權。

+0

請完整閱讀編譯器提供的錯誤消息。消息說:「幫助:爲了防止移動,使用'ref c1'或'ref mut c1'來通過引用捕獲值。如果您發現錯誤消息太混亂,請[提出問題](https://github.com/rust-lang/rust)描述更好的措辭或錯誤的表述會使錯誤更加明確。 – Shepmaster

+1

@Shepmaster我花了大約2個小時試圖弄清楚這一點。我知道它必須是簡單的,但是當我閱讀'ref c1'時,我對Rust很陌生,立即嘗試'&c1'。現在已經提到過了,當我第一次瀏覽文檔時,我確實記得在文檔中閱讀過'ref',但是我記得沒有看到與'&'不同的任何上下文,並立即將它放在腦海中。這是我真的不知道要問的正確問題的其中一種情況。現在已經解釋了,我在踢自己,因爲錯誤信息非常有幫助,我只是啞巴。 – Liam

回答

3

變化

.... 
Shape::Circle(c1) => ... 
.... 
Shape::Circle(c2) => ... 
.... 

.... 
Shape::Circle(ref c1) => ... 
.... 
Shape::Circle(ref c2) => ... 
.... 

Playground

let ref x = y;是基本上匹配的let x = &y;版本的圖案。

+0

@Liam你覺得這個還是其他答案你的問題?如果是這樣,你能接受一個答案嗎? – WiSaGaN

1

正如WiSaGan指出的那樣,您必須使用ref模式來創建對包含值的引用。您還可以同時簡化兩種形狀的代碼匹配:

impl Cookie { 
    fn has_same_radius(&self, other: &Cookie) -> bool { 
     match (&self.shape, &other.shape) { 
      (&Shape::Circle(ref c1), &Shape::Circle(ref c2)) => c1.r == c2.r, 
      _ => false, 
     } 
    } 
}