为什么要在特质对象上使用盒装对象?
在《鲁斯塔斯人的锈》一书中,作者写道:
从广义上讲,您需要在库中使用静态调度,并在二进制文件中使用动态调度。在图书馆中,您想允许用户决定哪种派遣最适合他们,因为您不知道他们的需求。
我想,在二进制案例中,他提到了这一点:
fn flexible_dispatch_method(_: &dyn MyTrait) {}
// static dispatch
//
let obj = MyType {};
flexible_dispatch_method(&obj);
// dynamic dispatch
//
let trait_obj: &dyn MyTrait = &MyType {};
flexible_dispatch_method(trait_obj);
给定上述情况,使用盒装对象而不是特质对象有什么优势?是因为需要使用生命时:
fn return_new_trait_object<'a>() -> &'a dyn MyTrait {
&MyType {}
}
还是还有其他东西?基于我的理解,在动态调度案例中,需要将对象分配在堆中,因此我认为盒装对象没有太大的区别。
In the book Rust for Rustaceans, the author writes:
Broadly speaking, though, you’ll want to use static dispatch in your libraries and dynamic dispatch in your binaries. In a library, you want to allow your users to decide what kind of dispatch is best for them, since you don’t know what their needs are.
I guess that, in the binary case, he refers to this:
fn flexible_dispatch_method(_: &dyn MyTrait) {}
// static dispatch
//
let obj = MyType {};
flexible_dispatch_method(&obj);
// dynamic dispatch
//
let trait_obj: &dyn MyTrait = &MyType {};
flexible_dispatch_method(trait_obj);
Given the above, what's the advantage of using boxed objects instead of trait objects? Is it because of the need to use lifetimes:
fn return_new_trait_object<'a>() -> &'a dyn MyTrait {
&MyType {}
}
or there is something else? Based on my understanding, in the dynamic dispatch case, the object needs to be allocated in the heap, anyway, so I presume there isn't much difference with a boxed object.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我认为您可能在这里误解了几件事。
dyn特征
的混凝土类型上的方法时,就会发生静态调度。这是编译器决定在编译时呼叫的功能的时候。dyn特征
的指针,包括box&lt; dyn特征&gt;
,&amp; dyn Trait
,arc&lt ; dyn特征&gt;
等。当您通过dyn特征
调用功能时,编译器插入代码以查找在运行时调用的函数,从而允许多态性和更大的灵活性。在您的代码中,
flexible_dispatch_method(_:&amp; dyn mytrait)
始终使用动态调度,这表明其参数具有类型&dyn mytrait
。静态调度的一个示例将是以下内容:通过此声明,您的第一个用法将使用静态调度,第二个用法将使用动态调度。
动态调度更加灵活一些,因为它避免了整个地方都有通用物质。这对于编写大型应用程序很有用,您可能想拥有多态性并轻松添加新的实现。但是,动态调度具有性能成本,因此这就是为什么库应尽可能将调度选择留给呼叫者的原因。
根据何时使用
&amp; dyn Trait
vsbox&lt; dyn特征&gt;
:这全都基于所有权。如果您想要一个拥有的特质对象使用box&lt; dyn特征&gt;
,并且如果您想要借来的特质对象,请使用&amp; dyn trait
。I think you might be misunderstanding a couple things here.
dyn Trait
. It's when the compiler decides which function to call at compile-time.dyn Trait
, includingBox<dyn Trait>
,&dyn Trait
,Arc<dyn Trait>
, etc. When you call a function through adyn Trait
, the compiler inserts code to lookup the function to call at runtime, allowing for polymorphism and greater flexibility.In your code,
flexible_dispatch_method(_: &dyn MyTrait)
always uses dynamic dispatch, as signaled by the fact that its argument has the type&dyn MyTrait
. An example of static dispatch would be the following:With this declaration your first usage would use static dispatch and the second would use dynamic dispatch.
Dynamic dispatch is a little more flexible since it avoids having generics all over the place. This can be useful for writing large applications where you might want to have polymorphism and easily add new implementations. However, dynamic dispatch has a performance cost, so that's why libraries should leave the dispatch choice up to the caller as much as possible.
As per when to use
&dyn Trait
vsBox<dyn Trait>
: it's all based on ownership. If you want an owned trait object useBox<dyn Trait>
, and if you want a borrowed trait object use&dyn Trait
.