引用枚举中的参数
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) => ...
....
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,
}
}
}
下面的代码给出了错误 "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) => ...
....
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,
}
}
}