i有一个从共享库中动态加载的接口集合。我希望能够将这些 dowcasted 接口转换为其原始类型(特质(。
struct A {}
fn abstract_a<'l>() -> &'l Any { return &A{} }
trait TargetTrait { fn some_method(); }
impl TargetTrait for A { fn some_method() { println!("HELLO"); } }
fn main() {
let x: &Any = abstract_a();
let y: &TargetTrait = magic_conversion<&TargetTrait> (x);
}
// question: does 'magic_conversion'(or 'dynamic_cast') exist? what is it?
加载这些问题不是问题时,我不知道如何通过这种接口获得 target 功能。换句话说:
/* simplified for readability */
// this part is known
let some_lib = loadlib("path/to/lib.so")
let some_interface: &Any = some_lib.loadfunc<&Any>("constructor_func")()
/* loader does not know what target type constructor has, so it presumes 'Any' */
// the problem:
let dependent_class = Some(class)
dependent_class.graphics = dynamic_cast<IGraphics>(some_interface)
在此示例中,dependent_class
使用外部界面,并且不在乎处理Libloading和所有这些复杂的内容。如果有另一种实现目标的方法,我也很高兴看到它,但是我提出的唯一解决方案是" Dynamic_cast"
我认为您要寻找的是downcast_ref::<A>
:
let y: &TargetTrait = Any::downcast_ref::<A>(x).expect("Expected an A");
您必须指定 concrete 类型A
。Any
特征对象没有任何有关基础类型的特征的信息,因此您不能直接从&Any
到&TargetTrait
"交叉播";您必须知道基础类型。
如果downcast_ref
返回None
,则expect
会恐慌;如果那不是您想要的,则必须决定当x
不是A
时要发生的事情,而是根据downcast_ref
的结果进行匹配。