2016-05-17 11 views
1

以下のコードは、「借用したコンテンツから移動できません」というエラーを示しています。私は、これについて既に多くの質問があることを知っています。私は、Rustを使用しているすべての人が、ここで自分自身をある時点で見つけて、所有権で何が起こっているのかを正確に把握しようとしていると思います。私はここで何が起こっているのか、どのように修正するのかを知っていると思います。私はこの特定の場合に参照を使用する方法を知らないだけです。私がしようとしていることを達成するためにもっと慣れ親しんだ方法があるなら、コメントに私に教えてください。列挙型内のパラメータへの参照

私は所有権を取得しようとしている場所を見ることができますが、代わりに参照を使用する方法がわかりません。

のはやや最小限の例を見てみましょう:

/* 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

コンパイラが提供するエラーメッセージを完全に読んでください。メッセージには "help:移動を防ぐために、' 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, 
     } 
    } 
} 
関連する問題