我想创建一个不可变的,引用数据类型,并添加如下:
use std::ops::Add;
struct Point {
x: i64,
y: i64,
}
impl<'a> Add for &'a Point {
type Output = Point;
fn add(self, other: &Point) -> Point {
Point {
x: self.x + &other.x,
y: self.y + &other.y,
}
}
}
Run Code Online (Sandbox Code Playgroud)
如何实现添加特征以引用结构?建议Add在引用类型上实现.
我可以做到这一点,在哪里a和b是Point:
let c = &a + &b;
let d = &c + &b;
Run Code Online (Sandbox Code Playgroud)
但不是这个:
let d = &a + &b + &b;
Run Code Online (Sandbox Code Playgroud)
我不介意这些&迹象,但不能连锁添加对我来说并不好看.我想实现乘法(z = a + b * c;或者如果必须的话z = &a + &b * &c;),如果我不必创建临时变量,它会更清晰.
有没有办法让它干净利落?包围似乎没有帮助.
我明白这是怎么回事,&a + &b给人以Point不是&Point,这表明我可以同时实现add(&Point, Point)与add(&Point, &Point)-但现在已经有4例,总让因为工作的所有组合a + b * c,并a * b + c有不同的优先级/解析树毕竟.有更好的方法吗?
我还想避免在非参考版本中进行不必要的复制.无论如何我正在返回一个新对象,所以首先克隆输入对我来说似乎是浪费时间.
我可能只是实现Add对值的引用:
impl<'a> Add<&'a Point> for Point {
type Output = Point;
fn add(self, other: &'a Point) -> Point {
Point {
x: self.x + &other.x,
y: self.y + &other.y,
}
}
}
Run Code Online (Sandbox Code Playgroud)
包围似乎没有帮助.
您可以参考表达式的一部分结果:
let d = &(&a + &b) + &b;
Run Code Online (Sandbox Code Playgroud)
我不确定这对你来说是否更好看.
现在共有4例
实际上,有4案件每个操作:(T, T),(T, &T),(&T, T),(&T, &T).
有更好的方法吗?
不是真的,但这是因为你的下一个要求......
我还想避免在非参考版本中进行不必要的复制
这就是为什么操作按值消耗,以允许您重用任何潜在的分配.在这种情况下Point,它(毫无意义)毫无意义,因为结构是如此之小.这类型更可信Vec.
所有这一切,人们通常使用宏来避免一遍又一遍地写同样的东西的苦差事.例如,标准库有一个宏,它假定类型实现Copy.但是,如果要重用分配,则意味着您不希望所有4个实现都相同.在最好的情况下,您可以编写两个实现(&T, &T),(T, &T)并从其余两个变体转发.
也可以看看: