引用枚举中的参数

Reference to parameters within an enum

下面的代码给出了错误 "cannot move out of borrowed content"。我知道这里已经有很多关于此的问题。我认为每个使用 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 中的参数,但由于我没有使用引用,所以我试图取得整个饼干结构。

改变

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

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

Playground

let ref x = y; 基本上是 let x = &y;.

的模式匹配版本

正如 所指出的,您必须使用 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,
        }
    }
}