【问题标题】:Several implementations of the Add trait for the same type同一类型的 Add trait 的几种实现
【发布时间】:2014-10-16 19:30:13
【问题描述】:

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

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);
}

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       }

最终我想像这样在我的类型 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 };

最好的方法是什么?

【问题讨论】:

标签: rust traits


【解决方案1】:

更新:

是的,您现在可以实施!

怎么样?类似下面的方式:

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);
}

解释。看你什么时候写

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

Rust 会查找所有已实现的 Add 特征 for A。问题是因为定义了两个:impl Add&lt;A, A&gt; for Aimpl Add&lt;int, A&gt; for A Rust 是“不确定”采用哪一个。不要引用我的话,因为 Rust 编译器内部不是我的一杯茶,但我认为 Rust 团队希望避免为多分派付出代价。

您的解决方案是:
A) 添加另一个特征,例如 answer,它将像给定的示例一样为您添加。
B)等待关联类型登陆,这是更好的选择。 (Issue #17307)
C) 放弃impl Add&lt;int, A&gt; for A

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

【讨论】:

  • 我认为这不是性能问题,而是对歧义和“板条箱可组合性”的担忧。我希望多个调度将很快登陆。至少对这类二元运算符非常有用。
猜你喜欢
  • 1970-01-01
  • 2023-03-06
  • 1970-01-01
  • 2015-05-31
  • 1970-01-01
  • 1970-01-01
  • 2015-03-16
  • 2022-08-19
  • 1970-01-01
相关资源
最近更新 更多