【问题标题】:Pass boxed trait as a reference传递盒装特征作为参考
【发布时间】:2014-05-19 16:42:59
【问题描述】:

所以我有一个特征,我想传递并执行一些动态方法调度。我有一个方法需要将特征作为盒装指针,但它需要调用另一个使用特征引用的方法。所以像:

trait Foo {
    fn do_something(&self);
}

struct Bar;

impl Foo for Bar {
    fn do_something(&self) {}
}

fn foo_as_box(foo : Box<Foo>) {
    foo_as_ref(&foo);
}

fn foo_as_ref(foo : &Foo) {
    foo.do_something();
}

fn main() {
    let boxed_foo = box Bar as Box<Foo>;
    foo_as_box(boxed_foo);
} 

但是,我收到此代码的错误

error: failed to find an implementation of trait Foo for Box Foo<no-bounds>

【问题讨论】:

    标签: rust


    【解决方案1】:

    编译器会根据需要自动将Box&lt;Foo&gt; 转换为&amp;Foo。你可以说

    foo_as_ref(foo);
    

    它会起作用的。

    这不一定适用于更复杂的情况。也就是说,编译器不能总是告诉你想要那个转换。

    现在DST已经实现了,你可以说&amp;*foo进行转换。

    过去,强制它的唯一方法是let-binding,如

    let ref_foo: &Foo = foo;
    

    当然,您的用例很简单,您不需要这个。

    【讨论】:

    • 是否应该让 Arc 到 &Foo 之类的 let-binding 也起作用?
    • @AJD:当然,如果您取消引用Arc(并不是说它实际上必须是Arc&lt;Box&lt;Foo:Send+Share&gt;&gt;,因为Arc 需要Send+Share)。 let boxed_foo = box Bar as Box&lt;Foo:Send+Share&gt;; let arc_foo = Arc::new(boxed_foo); let ref_foo: &amp;Foo = *arc_foo;
    • 这里是否使用了&amp;* 的运行时成本?
    • @SomeName &amp;* 将调用 Deref::deref() 但在大多数情况下,这应该是微不足道的,并且可能会得到优化。
    猜你喜欢
    • 2018-08-19
    • 2018-07-28
    • 2011-06-25
    • 2011-12-15
    • 2016-04-11
    • 2014-02-10
    • 1970-01-01
    • 2023-04-01
    • 2019-12-28
    相关资源
    最近更新 更多