编译以下使用运算符重载的Rust代码
use std::ops::{Add};
#[derive(Show)]
struct Point {
x: int,
y: int
}
impl Add for Point {
type Output = Point;
fn add(self, other: Point) -> Point {
Point {x: self.x + other.x, y: self.y + other.y}
}
}
fn main() {
let p: Point = Point {x: 1, y: 0};
let pp = p + p;
}
由于p:
的所有权导致编译器错误<anon>:21:18: 21:19 error: use of moved value: `p`
<anon>:21 let pp = p + p;
^
<anon>:21:14: 21:15 note: `p` moved here because it has type `Point`, which is non-copyable
<anon>:21 let pp = p + p;
^
其背后的基本原理被解释here并导致RFC未被接受(部分由于上述示例的原因)。但是,稍后,以下RFC仍然为运算符引入了按值类型的签名。
虽然我理解决定背后的理由。由于我缺乏生锈经验,我不确定允许上述代码工作的“正确”方法是什么(a)如果我不想复制或(b)如何使结构可复制?
答案 0 :(得分:4)
如果您不想复制,那么就我的新手理解而言,您需要对Add
的引用实施Point
。
这将得到RFC的支持:
幸运的是,表达性没有任何损失,因为您始终可以在引用类型上实现特征。但是,对于需要通过引用获取的类型,人体工程学会略有损失,因为您可能需要使用&amp;显式地借用操作数。好处是所有权语义变得更加清晰:它们更类似于正常的函数参数。
确实似乎有效:
use std::ops::{Add};
#[derive(Show)]
struct Point {
x: i32,
y: i32
}
impl<'a> Add for &'a Point {
type Output = Point;
fn add(self, other: &'a Point) -> Point { //'
Point {x: self.x + other.x, y: self.y + other.y}
}
}
fn main() {
let p: Point = Point {x: 1, y: 0};
let pp = &p + &p;
println!("{:?}", pp);
}
(playpen)
要使Point
可复制,只需将#[derive(Show)]
替换为#[derive(Show,Copy)]
即可。这些结构在默认情况下是可复制的,但changed。
答案 1 :(得分:4)