Rust 中不止一个运算符重载

nya*_*108 5 c++ operator-overloading rust

我知道通过使用特征在 Rust 中实现运算符重载是可能的。在 C++ 中,也可以对同一个运算符和相同的 进行多个运算符重载struct,并打开/关闭要使用的运算符。

是否可以在 Rust 中执行与以下 C++ 代码相同的操作?可能在同一个源文件中?

struct S
{
    int value;
};

namespace first
{
S operator+(S lhs, S rhs)
{
    return S{ lhs.value + rhs.value };
}
}

namespace second
{
S operator+(S lhs, S rhs)
{
    return S{ lhs.value * rhs.value };
}
}

int main()
{
    S s1{5};
    S s2{10};
    {
        using namespace first;
        S s3 = s1 + s2;
        std::cout << s3.value << std::endl;
    }
    {
        using namespace second;
        S s3 = s1 + s2;
        std::cout << s3.value << std::endl;
    }
}
Run Code Online (Sandbox Code Playgroud)

Mat*_* M. 7

Rust 中惯用的答案是:

如何为我的类型使用 +、<、... 的不同重载?

是包装类型并在包装器上实现运算符。

操场上的例子

#[derive(Clone, Copy, Debug)]
struct S(i32);

#[derive(Debug)]
struct Adder(pub S);

impl std::ops::Add<S> for Adder {
    type Output = S;

    fn add(self, other: S) -> S { S(self.0.0 + other.0) }
}

impl std::ops::Add<Adder> for S {
    type Output = S;

    fn add(self, other: Adder) -> S { S(self.0 + other.0.0) }
}

#[derive(Debug)]
struct Multiplier(pub S);

impl std::ops::Add<S> for Multiplier {
    type Output = S;

    fn add(self, other: S) -> S { S(self.0.0 * other.0) }
}

impl std::ops::Add<Multiplier> for S {
    type Output = S;

    fn add(self, other: Multiplier) -> S { S(self.0 * other.0.0) }
}

fn main() {
    let one = S(5);
    let two = S(10);

    println!("{:?}", one + Adder(two));
    println!("{:?}", Adder(one) + two);
    
    println!("{:?}", one + Multiplier(two));
    println!("{:?}", Multiplier(one) + two);
}
Run Code Online (Sandbox Code Playgroud)

这种习惯用法可以在标准库中看到,其中std::num::Wrapping类型可用于包装整数,在这种情况下,加法、减法和乘法被重新定义为使用模算术。