我正在尝试在 Rust 中为具有子类型的特征实现 PartialEq,以便我可以将它们作为盒装指针添加到容器中,然后进行比较.
I'm trying to implement PartialEq in Rust for a trait that has subtypes, so that I can add them as boxed pointers to a container and later compare them.
这是我的缩小实施:
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); }Rust Playground 中的代码示例.
当我构建这个时,我得到:
When I build this, I get:
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这令人困惑.知道我在这里做错了什么吗?
which is confusing. Any ideas what I'm doing wrong here?
编辑:我不认为这是 为什么 Rust 不支持 trait 对象向上转换?,因为我要做的是使用 Any 进行向下转换,而不是向上转换.
Edit: I don't believe this is a duplicate of Why doesn't Rust support trait object upcasting?, because what I'm trying to do is downcast using Any, not upcast.
进一步编辑:是的,这是重复的 - 抱歉,我在想我要做什么(向下转换到 Bar 和 Baz 类型)而不是我是如何做的(向上转换为 Any).但是,话虽如此,我想我仍然不明白为什么 任何示例,他们这样做的地方: let value_any = value as &Any; 有效,而我的却没有.话虽如此,Joshua Entrekin 确实给出了很好的答案.
Further Edit: Yes, this is a duplicate - sorry, I was thinking about what I was trying to do (downcast to the Bar and Baz types) rather than how I was doing that (upcasting to Any). However, that being said, I guess I still don't understand why the Any example, where they do this: let value_any = value as &Any; works, where mine doesn't. That being said, Joshua Entrekin did give a great answer.
最终编辑 一个,没关系,这是因为我在提升一种特质而不是一种类型 - Doh!.谢谢大家!
Final Edit An, never mind, it's because I'm upcasting a trait rather than a type - Doh!. Thanks, everyone!
推荐答案这是 为什么 Rust 不支持 trait 对象向上转换? 因为您正在尝试从 Foo 向上转换为 Any.如果您向 Foo 添加一个 as_any 方法并在其上实现,则可以使此代码工作:
This is a duplicate of Why doesn't Rust support trait object upcasting? because you are trying to upcast from Foo to Any. If you add an as_any method to Foo and implement on it, this code can be made to work:
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 中展示了它.
更多推荐
在 Rust 中使用 Any 和 trait
发布评论