Rust会自动获取一个值的不可变引用吗



我有一个结构,它实现了几个运算符:

use std::ops;
/// Vector of 3 floats
#[derive(Debug, Copy, Clone)]
pub struct Vec3 {
pub x: f32,
pub y: f32,
pub z: f32,
}
/// Add operator
impl ops::Add<&Vec3> for &Vec3 {
type Output = Vec3;
#[inline(always)]
fn add(self, rhs: &Vec3) -> Self::Output {
Vec3 {
x: self.x + rhs.x,
y: self.y + rhs.y,
z: self.z + rhs.z,
}
}
}
/// Subtract operator
impl ops::Sub<&Vec3> for &Vec3 {
type Output = Vec3;
#[inline(always)]
fn sub(self, rhs: &Vec3) -> Self::Output {
Vec3 {
x: self.x - rhs.x,
y: self.y - rhs.y,
z: self.z - rhs.z,
}
}
}
/// Scalar multiplication operator
impl ops::Mul<&Vec3> for f32 {
type Output = Vec3;
#[inline(always)]
fn mul(self, rhs: &Vec3) -> Self::Output {
Vec3 {
x: self * rhs.x,
y: self * rhs.y,
z: self * rhs.z,
}
}
}

我想使用运营商:

let a = Vec3 { x: 0.0, y: 0.5, z: 1.0 };
let b = Vec3 { x: 1.0, y: 0.5, z: 0.0 };
let c = Vec3 { x: 1.0, y: 1.0, z: 0.0 };
let d = Vec3 { x: 0.0, y: 1.0, z: 1.0 };
let result = 2.0 * (a + b) - 3.0 * (c - d);

此代码将不会编译,因为运算符是为&Vec3实现的,而不是为Vec3实现的。为了解决这个问题,最后一行必须是这样的:

let result = &(2.0 * &(&a + &b)) - &(3.0 * &(&c - &d));

看起来不再那么好看了。

我知道我可以实现Vec3的运算符来避免这个问题,但如果我仍然想在堆栈上使用对这些向量的不可变引用呢?有没有一种方法可以给Rust一些提示,如果我写a + b,而Vec3 + Vec3没有运算符,它可以尝试寻找&Vec3 + &Vec3运算符,如果找到,则自动为两个参数获取不可变的引用?

不,当添加两个值时,没有办法自动获取引用。

我想,你可以编写自己的宏来实现这一点。在使用中,它看起来像:

thing!{ a + b }
// expands to
(&a + &b)

我预计这个宏会很快变得令人厌倦。

另请参阅:

  • 允许运算符中的autoderef和autoref——RFC#2147
  • 跟踪问题:允许运算符中的autoderef和autoref(实验(#44762
  • 打印!借用还是拥有变量
  • 如何在Rust中实现值和引用的惯用运算符重载
  • 运算符按值重载导致使用移动的值
  • 如何为引用类型实现Add这样的运算符,以便一次添加两个以上的值

最新更新