【问题标题】:Reference to parameters within an enum引用枚举中的参数
【发布时间】:2016-09-13 00:26:54
【问题描述】:

下面的代码给出了错误“无法移出借用的内容”。我知道这里已经有很多关于这个的问题。我认为每个使用 Rust 的人都会在某一时刻发现自己,试图弄清楚所有权到底发生了什么。我想我知道这里发生了什么以及如何解决它,我只是不知道如何在这种特殊情况下使用参考。如果有更惯用的方式来完成我正在尝试的事情,请在 cmets 中告诉我。

我可以看到我试图在哪里取得所有权,但我不确定如何使用参考。

让我们看一个小例子:

/* 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 结构的所有权。

【问题讨论】:

  • 请完整阅读编译器提供的错误信息。该消息显示“帮助:为防止移动,请使用ref c1ref mut c1 通过引用获取值”。如果您发现错误消息过于混乱,请file an issue 描述错误的更好措辞或呈现方式会更清楚。
  • @Shepmaster 我花了大约 2 个小时试图弄清楚这一点。我知道它必须是一些简单的东西,但是当我阅读 ref c1 时,我对 Rust 不熟悉,立即尝试了 &c1。既然有人提到了它,我记得当我第一次阅读它时,我在文档中读过关于 ref 的内容,但我记得没有看到任何与 & 不同的上下文,并立即将其忘掉。这是我什至不知道该问正确问题的情况之一。既然已经解释过了,我在踢自己,因为错误消息非常有帮助,我只是愚蠢。

标签: rust match ownership


【解决方案1】:

改变

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

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

Playground

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

【讨论】:

  • @Liam 你觉得这个或其他回答了你的问题吗?如果是这样,您能接受其中一个答案吗?
【解决方案2】:

正如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,
        }
    }
}

【讨论】:

    猜你喜欢
    • 2010-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多