Rust无法找到特征实现

时间:2018-08-15 22:52:41

标签: reference rust traits

我正在尝试为实现另一特征的任何事物实现Add特征(在示例代码中为Test特征)。我在Add实现中使用引用,因为并非所有实现Test的东西都具有相同的大小。下面的代码可以正常编译:

use std::ops::Add;

struct Foo(i32);
struct Bar(i64);

trait Test {}

impl Test for Foo {}
impl Test for Bar {}

impl<'a, 'b> Add<&'b Test> for &'a Test {
    type Output = Box<Test>;

    fn add(self, other: &'b Test) -> Box<Test> {
        if true {
            Box::new(Foo(5))
        } else {
            Box::new(Bar(5))
        }
    }   
}

如下所示,当我尝试实际使用Add时,它说该操作无法应用,因为缺少Add的{​​{1}}的实现。

&Foo

我对实现的定义有误吗?我打错了吗?目标是使函数add对实现了fn test_add() { &Foo(5) + &Bar(5) } 的对象进行两个引用,并返回对实现Test的新对象的引用(或框)(并且可能不是相同的基础类型作为输入之一。

2 个答案:

答案 0 :(得分:0)

我发现了另一种可以稍微改变行为但有效的方法。

struct V<T>(T);

use std::ops::Add;
impl<T1: Test, T2: Test> Add<V<Box<T2>>> for V<Box<T1>> {
    type Output = V<Box<Test>>;
    fn add(self, other: V<Box<T2>>) -> Self::Output {
        unimplemented!()
    }
}

这允许它返回实现Test的任何类型,但代价是将所有内容包装在Box和伪结构V中。不是很优雅,我仍然不明白为什么我的原始代码不起作用,但是至少这具有我想要的行为。

答案 1 :(得分:0)

问题在于编译器无法从&Foo隐式转换为&Test。如果先将其明确转换为&Test,则运算符重载将起作用:

fn test_add() {
    let foo: &Test = &Foo(5);
    foo + &Bar(5);
}

或者,您可以使用fully qualified syntax

fn test_add() {
    <&Test as Add<&Test>>::add(&Foo(5), &Bar(5));
}