![](/img/trans.png)
[英]Why doesn't a trait implementation compile for a struct, but it compiles for a reference to the struct?
[英]Rust can't find trait implementation
我正在尝试为实现另一个特征的任何东西(在示例代码中为Test
trait)实现Add
trait。 我在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
for &Foo
的实现。
fn test_add() {
&Foo(5) + &Bar(5)
}
我是否定义了错误的实现? 我打错了吗? 我们的目标是使附加功能需要两个引用这两个实施对象Test
,并返回一个引用(或箱),以实现一个新的对象Test
(和可能不是相同的基本类型,其中一个输入)。
我发现了另一种方法,可以稍微改变行为,但可以。
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
。 不是很优雅,我仍然不明白为什么我的原始代码不起作用,但是至少它具有我想要的行为。
问题在于,编译器无法将&Foo
隐式转换为&Test
。 如果首先将其显式转换为&Test
,则运算符重载将起作用:
fn test_add() {
let foo: &Test = &Foo(5);
foo + &Bar(5);
}
另外,您可以使用完全限定的语法 :
fn test_add() {
<&Test as Add<&Test>>::add(&Foo(5), &Bar(5));
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.