我正在尝试在Rust中为具有子类型的特征实现PartialEq
,以便我可以将它们添加为容器的盒装指针,然后进行比较。
这是我的缩小实施:
use std::any::Any;
trait Foo: Any {}
struct Bar {}
impl Foo for Bar {}
struct Baz {}
impl Foo for Baz {}
impl PartialEq for Foo {
fn eq(&self, other: &Foo) -> bool {
let me = self as &Any;
let you = other as &Any;
if me.is::<Bar>() && you.is::<Bar>() {
true
} else if me.is::<Baz>() && you.is::<Baz>() {
true
} else {
false
}
}
}
fn main() {
let bar: Bar = Bar {};
let baz: Baz = Baz {};
let foo1: &Foo = &bar;
let foo2: &Foo = &baz;
println!("{:?}", foo1 == foo2);
}
Code example in Rust Playground
当我建立这个时,我得到:
rustc 1.17.0-nightly (0648517fa 2017-02-03)
error: non-scalar cast: `&Foo + 'static` as `&std::any::Any + 'static`
--> <anon>:15:18
|
15 | let me = self as &Any;
| ^^^^^^^^^^^^
error: non-scalar cast: `&Foo + 'static` as `&std::any::Any + 'static`
--> <anon>:16:19
|
16 | let you = other as &Any;
| ^^^^^^^^^^^^^
error: aborting due to 2 previous errors
令人困惑。我在这里做错了什么想法?
修改:我不认为这是Why doesn't Rust support trait object upcasting?的副本,因为我要做的是使用Any
进行向下转换,而不是向上转发。
进一步编辑:是的,这是重复的 - 对不起,我正在考虑我要做的事情(向下转换为Bar
和Baz
类型)而不是我这样做(向上转移到Any
)。然而,话虽如此,我想我仍然不明白为什么Any example,他们这样做:let value_any = value as &Any;
有效,而我的不行。话虽如此,Joshua Entrekin确实给出了一个很好的答案。
最终编辑一个,没关系,这是因为我正在向上倾斜一个特征而不是一个类型 - Doh!。谢谢大家!
答案 0 :(得分:7)
这是Why doesn't Rust support trait object upcasting?的副本,因为您正尝试从Foo
转播到Any
。如果您向as_any
添加Foo
方法并对其进行实施,则可以使此代码生效:
use std::any::Any;
trait Foo: Any {
fn as_any(&self) -> &Any;
}
impl<T: Any> Foo for T {
fn as_any(&self) -> &Any {
self
}
}
struct Bar {}
struct Baz {}
impl PartialEq for Foo {
fn eq(&self, other: &Foo) -> bool {
let me = self.as_any();
let you = other.as_any();
if me.is::<Bar>() && you.is::<Bar>() {
true
} else if me.is::<Baz>() && you.is::<Baz>() {
true
} else {
false
}
}
}
fn main() {
let bar: Bar = Bar {};
let baz: Baz = Baz {};
let foo1: &Foo = &bar;
let foo2: &Foo = &baz;
println!("{:?}", foo1 == foo2);
}
我在Playground显示它。