简体   繁体   中英

Require commutative operation in Rust trait bound

Suppose I have a group of related non-scalar structs with a commutative arithmetic operation defined on them. For example,

struct Foo {
    a: f64,
    b: f64
}

impl Add<f64> for Foo {
    type Output = Foo;
    
    fn add(self, v: f64) -> Self::Output {
        Foo {
            a: self.a + v,
            b: self.b + v
        }
    }
}

impl Add<Foo> for f64 {
    type Output = Foo;
    
    fn add(self, foo: Foo) -> Self::Output {
        Foo {
            a: foo.a + self,
            b: foo.b + self
        }
    }
}

I want to implement a trait on this group of structs, taking advantage of this operation. That is, I want something like the following:

trait Bar: Add<f64, Output = Self> + Sized {
    fn right_add(self, f: f64) -> Self {
        self + f
    }
    
    // Doesn't compile!
    fn left_add(self, f: f64) -> Self {
        f + self
    }
}

However, this currently doesn't compile, since the super-trait bound doesn't include the left addition of f64 to Self . My question is: How can I state this commutative trait bound?

( Playground link .)

Edit: To be clear, I'm aware that right_add and left_add have the same output. I'm mainly interested in the ergonomics of not having to remember which is "correct" according to the compiler. In addition, I'm curious to learn how to do this, even if it's not strictly necessary.

Inverted trait bounds like this are the exact usecase for where syntax:

trait Bar
where
    f64: Add<Self, Output = Self>,
    Self: Add<f64, Output = Self> + Sized,
{
    fn right_add(self, f: f64) -> Self {
        self + f
    }

    fn left_add(self, f: f64) -> Self {
        f + self
    }
}

Playground link

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM