我遇到了这个问题,我想知道为什么它不起作用。 我成功地复制了这个问题:
我正在尝试从
&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
,但如果这有效,则没有。
你不能只说
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"),
}
}
链接的答案中有更多解释,我鼓励您阅读。
遇到类似的问题,给我的建议是在
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)
}
}
无论哪种情况,您都不需要任何魔法来获取对原始结构的引用。