我正在尝试PartialEq在Rust中实现具有子类型的特征,以便我可以将它们作为盒装指针添加到容器中,然后比较它们.
这是我缩小的实现:
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);
}
Run Code Online (Sandbox Code Playgroud)
当我构建这个时,我得到:
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
Run Code Online (Sandbox Code Playgroud)
这令人困惑.我在这里做错了什么想法?
编辑:我不相信这是一个副本为什么不支持特技对象向上转换?因为我要做的就是贬低使用Any,而不是向上.
进一步编辑:是的,这是一个重复 - 对不起,我正在考虑我想要做什么(向下转向Bar和Baz类型),而不是我是如何做到的(向上转发Any).然而,话虽这么说,我想我仍然不明白为什么任何一个例子,他们这样做:let value_any = value as &Any;工作,我的没有.话虽如此,Joshua Entrekin确实给出了一个很好的答案.
最后编辑一个,没关系,这是因为我正在向上倾斜一个特征而不是一个类型 - Doh!.感谢大家!
小智 8
这是为什么Rust不支持特征对象向上转换的副本?因为你是从试图上溯造型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);
}
Run Code Online (Sandbox Code Playgroud)
我在游乐场里展示它.