无法从 &mut Box<dyn Trait> 向下转换为 &mut dyn Any?

问题描述 投票:0回答:2

我遇到了这个问题,我想知道为什么它不起作用。 我成功地复制了这个问题:

我正在尝试从

&mut Box<dyn Trait>
返回结构,这就是我的尝试:

use std::any::Any;

trait A {}

struct B;

impl A for B {}

fn main() {
    let mut a: Box<dyn A> = Box::new(B);
    let a_ref: &mut Box<dyn A> = &mut a;

    match (a_ref as &mut dyn Any).downcast_mut::<B>() { // downcast here 
        Some(_b) => println!("found b"),
        None => println!("found nothing")
    }
}

但是这并没有找到背后的结构体?我是不是漏掉了什么?

这是游乐场的链接

我尝试过向下转型为其他事物,例如

Box<B>
&mut B
,但如果这有效,则没有。

rust downcast
2个回答
1
投票

你不能只说

my_trait_object as &dyn Any
并期望能够向下转换为原始类型。它不会神奇地工作,你需要 original 类型来强制自己为
dyn Any
,这是它工作的唯一方式。这就是为什么这里的解决方案需要通过特征对象,获取原始类型,将其获取为
Any
如何从特征对象获取对具体类型的引用?

这里发生的情况是,具体类型被强制转换为

dyn Any
,但该具体类型是
Box<dyn A>
。此代码打印“找到的框”:

use std::any::Any;

trait A {}
struct B;
impl A for B {}

fn main() {
    let mut a: Box<dyn A> = Box::new(B);
    let a_ref: &mut Box<dyn A> = &mut a;

    match (a_ref as &mut dyn Any).downcast_mut::<Box<dyn A>>() {
        Some(_) => println!("found box"),
        None => println!("found nothing"),
    }
}

链接的答案中有更多解释,我鼓励您阅读。


0
投票

遇到类似的问题,给我的建议是在

A
中有一个方法,可以选择返回对结构的引用。

trait A {
    fn as_b(&mut self) -> Option<&mut B> { None }
}

impl A for B {
    fn as_b(&mut self) -> Option<&mut B> {
        Some(self)
    }
}

我的想法是确定您真正想要的

B
的接口,并将其抽象为一个单独的特征。这使得界面更加干净,因为它不依赖于单个结构:

trait C {}

trait A {
    fn as_c(&mut self) -> Option<&mut dyn C> { None }
}

impl C for A {}

impl A for B {
    fn as_c(&mut self) -> Option<&mut B> {
        Some(self)
    }
}

无论哪种情况,您都不需要任何魔法来获取对原始结构的引用。

© www.soinside.com 2019 - 2024. All rights reserved.