我有一组从共享库动态加载的接口。我希望能够将那些 downcasted 接口转换为原始类型(特征)。
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?
虽然加载这些不是问题,但我不知道如何使用此类界面获取目标功能。换句话说:
/* 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
使用extern接口,而不关心处理libloading和所有复杂的东西。
如果有另一种方法可以实现我的目标,我也很乐意看到它,但我提出的唯一解决方案是'dynamic_cast'
答案 0 :(得分:4)
我认为你要找的是downcast_ref::<A>
:
let y: &TargetTrait = Any::downcast_ref::<A>(x).expect("Expected an A");
您必须指定具体类型A
。 Any
特征对象不包含有关基础类型所实现的特征的任何信息,因此您无法直接从&Any
“交叉投射”到&TargetTrait
;你必须知道基础类型。
如果expect
返回downcast_ref
,None
会发生恐慌;如果那不是您想要的,那么当x
不是A
并且与downcast_ref
的结果匹配时,您必须决定要发生什么。