rust - (Rust) 有没有办法为重载的运算符自动借用?

标签 rust

我正在尝试在 Rust 中实现一个基本的多项式类型,其中包含用于数学运算的重载运算符。到目前为止,我可以通过重载运算符来设法实现加法、减法等基本操作。问题是,我想通过引用来获取操作数以避免不必要的复制。 IE。 :

impl ops::Add for &Polynomial {
    type Output = Polynomial;
    fn add(self, other: Self) -> Polynomial {
        let mut result = self.clone();
        for (power, coeff) in other.coefficients.iter().enumerate() {
            result.add_coeff(power, *coeff);
        }
        result
    }
}
impl ops::Sub for &Polynomial {
    //  Implementation
    //  ...
}
impl ops::Mul for &Polynomial {
    //  Implementation
    //  ...
}
//  Etc.

这按预期工作,但是它强制用户每次都明确地借用操作数,随着表达式变得更复杂,这变得更难读:

let (quotient, remainder) = p2.div_rem(&p1);

assert_eq!(&(&quotient * &p1) + &remainder, p2);

//  Even worse example found on the internet.
//  Note that you need to explicitly borrow each and every intermediate result :
let result = &(&(&a * &b) + &(&c * &d)) / 2;

除了最后两行,我认为如果我可以写的话会更清晰易读:

assert_eq!(quotient * p1 + remainder, p2);

let result = (a * b + c * d) / 2;

…让借用“自动”发生(就像你调用一个方法时所做的那样,它有一个 &self 作为任何值的第一个参数:它是自动和隐式借用的,而不必明确借用它)。

但是我不知道是否可以做,或者怎么做?

最佳答案

AFAIK,不,没有简单的方法来做到这一点,因为 Rust 引用总是显式的,从不隐式的,由于两种设计选择(即避免 C++ 引用的相同设计问题,这很奇怪 ) 和必要性(由于借用检查器)。

T, &T, &mut T, *const T, ... 都是不同的类型具有不同的语义,所以允许 impl ops::Add for &Polynomial 也适用于 Polynomial 基本上意味着 impl ops::Add for &T 将自动实现 ops::Add for T,这可能会导致非常奇怪且可能不安全的结果,特别是如果相反的情况也是如此。那么 &mut 呢? &mut T 会自动衰减为 &,对借用本身的生命周期有何影响?

此外,在非 Copy 值类型上实现 ops::Add 非常奇怪,因为运算符随后导致其操作数被移入 - 这绝对是这不是人们在大多数情况下使用 + 时所期望的。

关于rust - (Rust) 有没有办法为重载的运算符自动借用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67457210/

相关文章:

struct - 递归打印 struct in `fmt::Display`

generics - 使用泛型类型时如何使用整数文字?

rust - 有什么理由不对不迭代一系列事物的迭代器使用 DoubleEndedIterator 吗?

rust - 将默认参数传递给 cargo

generics - 如何定义采用 Mutex<T> 的通用函数?

rust - 没有方法解析字符串

generics - 如何编写采用 `u32` 或 `&u32` 的任何迭代器的通用函数?

rust - 在 for 循环中从 DirEntry 获取文件信息

rust - 在 Rust 中正确设置生命周期和可变性期望

rust - 您可以使用 impl Fn 接受任意大小的闭包作为参数吗?