相同类型的 Add trait 的几种实现

gbu*_*rri 2 traits rust

我正在尝试做一些非常简单的事情:

fn main() {   
   #[deriving(Show)]
   struct A {
      a: int
   }

   impl Add<A, A> for A {
      fn add(&self, other: &A) -> A {
         A { a: self.a + other.a }
      }
   }

   impl Add<int, A> for A {
      fn add(&self, v: &int) -> A {
         A { a: self.a + *v }
      }
   }   

   let x = A { a: 10 } + A { a: 20 };

   println!("x: {}", x);
}
Run Code Online (Sandbox Code Playgroud)

Rust compile 不喜欢我的代码并说:

src/sandbox.rs:20:12: 20:37 error: multiple applicable methods in scope [E0034]
src/sandbox.rs:20    let x = A { a: 10 } + A { a: 20 };
                             ^~~~~~~~~~~~~~~~~~~~~~~~~
src/sandbox.rs:8:7: 10:8 note: candidate #1 is `main::A.Add<A, A>::add`
src/sandbox.rs:8       fn add(&self, other: &A) -> A {
src/sandbox.rs:9          A { a: self.a + other.a }
src/sandbox.rs:10       }
src/sandbox.rs:14:7: 16:8 note: candidate #2 is `main::A.Add<int, A>::add`
src/sandbox.rs:14       fn add(&self, v: &int) -> A {
src/sandbox.rs:15          A { a: self.a + *v }
src/sandbox.rs:16       }
Run Code Online (Sandbox Code Playgroud)

最终,我想在我的类型 A 中添加一个 int 类型:

let x: A = A { a: 10 } + A { a: 20 };
let y: A = A { a: 10 } + 20i;
let z: A = A 10i + { a: 20 };
Run Code Online (Sandbox Code Playgroud)

最好的方法是什么?

Dan*_*ath 5

更新:

是的,您现在就可以实施!

如何?以类似于以下的方式:

use std::ops::Add;

#[derive(Debug)]
struct A {
      a: i32,
}


impl Add<i32> for A {
    type Output = A;

    fn add(self, _rhs: i32) -> A {
        A { a : self.a + _rhs }
    }
}

impl Add<A> for A {
    type Output = A;

    fn add(self, _rhs: A) -> A {
        A { a : self.a + _rhs.a }
    }
}

fn main() {   
    let x = A { a: 10 } + A { a: 20 };
    let y = A { a: 40 } + 2; 

    println!("x: {:?}\ny: {:?}", x, y);
}
Run Code Online (Sandbox Code Playgroud)

解释。看你什么时候写

let x = A { a: 10 } + A { a: 20 };
Run Code Online (Sandbox Code Playgroud)

Rust 查找所有已实现的 Add trait for A。问题是因为有两个定义:impl Add<A, A> for Aimpl Add<int, A> for ARust 是“不确定”要采用哪一个。不要引用我的话,因为 Rust 编译器内部结构不是我的菜,但我认为 Rust 团队希望避免为多分派付出代价。

您的解决方案是:
A)添加另一个特征,如此答案中所示,它将为您添加示例中的示例。
B) 等待关联类型登陆,这是更好的选择。(问题 #17307
C) 放弃impl Add<int, A> for A.

我想你想要的是多分派,应该很快就会登陆。有关详细信息,请参阅此RFC #195