有没有办法将特征引用转换为另一个未连接类型的对象?

时间:2018-02-24 00:32:08

标签: dynamic plugins rust

我有一组从共享库动态加载的接口。我希望能够将那些 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'

1 个答案:

答案 0 :(得分:4)

我认为你要找的是downcast_ref::<A>

let y: &TargetTrait = Any::downcast_ref::<A>(x).expect("Expected an A");

您必须指定具体类型AAny特征对象不包含有关基础类型所实现的特征的任何信息,因此您无法直接从&Any“交叉投射”到&TargetTrait;你必须知道基础类型。

如果expect返回downcast_refNone会发生恐慌;如果那不是您想要的,那么当x不是A并且与downcast_ref的结果匹配时,您必须决定要发生什么。