【发布时间】:2017-02-05 19:41:11
【问题描述】:
我正在尝试在 Rust 中为具有子类型的 trait 实现 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!。谢谢大家!
【问题讨论】:
-
我对这门语言太陌生了,无法告诉你所有的选择,但它看起来有点像你在尝试做 OO 风格的子类型。您是否尝试过使用某种枚举?
-
@JustinBlank 试过了,但是没有地方可以放 num AFAICT - 你不能给特征添加枚举,如果我做一个全局枚举,感觉很笨拙。 Any 的文档暗示,如果您的类型是 Any,您应该能够进行我正在做的那种转换 - 因此我的问题。
-
您的编辑对我来说没有意义,我认为存在术语差异。您正在尝试将
&Foo转换为&Any,在层次结构中向上。那是向上的。你为什么说你想低调? @JoshuaEntrekin also provides an example 这似乎有效。 -
@Shepmaster 抱歉,我评论了他的回复,但没有更新我的帖子。见上文。