简体   繁体   English

Rust找不到特质实现

[英]Rust can't find trait implementation

I'm trying to implement the Add trait for anything that implements another trait (in the example code the Test trait). 我正在尝试为实现另一个特征的任何东西(在示例代码中为Test trait)实现Add trait。 I'm using references in the Add implementation because not everything that implements Test will be the same size. 我在Add实现中使用引用,因为并非所有实现Test东西都具有相同的大小。 The code below compiles fine: 下面的代码可以正常编译:

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

When I try to actually use Add , as below, it says that the operation could not be applied because the implementation of Add for &Foo is missing. 如下所述,当我尝试实际使用Add ,它说该操作无法应用,因为缺少Add for &Foo的实现。

fn test_add() {
    &Foo(5) + &Bar(5)
}

Have I defined the implementation incorrectly? 我是否定义了错误的实现? Have I called it incorrectly? 我打错了吗? The goal is to make the function add take two references to objects which both implement Test , and return a reference (or box) to a new object that implements Test (and might not be the same underlying type as either of the inputs). 我们的目标是使附加功能需要两个引用这两个实施对象Test ,并返回一个引用(或箱),以实现一个新的对象Test (和可能不是相同的基本类型,其中一个输入)。

I found another approach that changes the behavior slightly, but works. 我发现了另一种方法,可以稍微改变行为,但可以。

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!()
    }
}

That allows it to return any type that implements Test , at the cost of wrapping everything in a Box and a dummy struct V . 这样一来,它就可以返回实现Test任何类型,但需要将所有内容包装在Box和虚拟结构V Not very elegant, and I still don't understand why my original code doesn't work, but at least this has the behavior I wanted. 不是很优雅,我仍然不明白为什么我的原始代码不起作用,但是至少它具有我想要的行为。

The problem is that the compiler cannot implicitly convert from &Foo into &Test . 问题在于,编译器无法将&Foo隐式转换为&Test If you explicitly convert it into &Test first, then the operator overloading works: 如果首先将其显式转换为&Test ,则运算符重载将起作用:

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

Alternatively, you can use the fully qualified syntax : 另外,您可以使用完全限定的语法

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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