【问题标题】:Rust can't find trait implementationRust 找不到 trait 实现
【发布时间】:2019-10-21 16:03:44
【问题描述】:

我正在尝试为实现另一个特征的任何东西实现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时,如下所示,它说无法应用该操作,因为缺少&amp;FooAdd实现。

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

我是否错误地定义了实现?我叫错了吗?目标是使函数 add 获取对都实现 Test 的对象的两个引用,并返回对实现 Test 的新对象的引用(或框)(并且可能与其中任何一个的底层类型不同)输入)。

【问题讨论】:

标签: reference rust traits


【解决方案1】:

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

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 中。不是很优雅,我仍然不明白为什么我的原始代码不起作用,但至少这有我想要的行为。

【讨论】:

  • 你可以把它和你原来的方法结合起来避免Boxing一切:impl&lt;'a, 'b, T1: Test, T2: Test&gt; Add&lt;V&lt;&amp;'b T2&gt;&gt; for V&lt;&amp;'a T1&gt;
【解决方案2】:

问题在于编译器无法将&amp;Foo 隐式转换为&amp;Test。如果您先将其显式转换为&amp;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));
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-06
    • 2023-03-26
    • 1970-01-01
    • 2018-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多