在 Rust 中使用 Any 和 trait [英] Using Any with traits in Rust

查看:146
本文介绍了在 Rust 中使用 Any 和 trait的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在 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.

进一步编辑:是的,这是重复的 - 抱歉,我在想我要做什么(向下转换到 BarBaz 类型)而不是我是如何做的(向上转换为 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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆