为什么特征对象通常通过引用(&dyn Trait)或智能指针(如 Box)来使用<dyn Trait)?

问题描述 投票:0回答:1

在 Rust 中,为什么特征对象通常通过引用(&dyn 特征)或智能指针(如 Box)来使用

它们是通过引用和智能指针处理的,因为否则它们将无法编译:

trait Foo {}
struct Bar;
impl Foo for Bar {}

fn main() {
    let f1: dyn Foo = Bar;
    let f2: dyn Foo = Bar as dyn Foo;
}
error[E0308]: mismatched types
 --> src/main.rs:6:23
  |
6 |     let f1: dyn Foo = Bar;
  |             -------   ^^^ expected `dyn Foo`, found `Bar`
  |             |
  |             expected due to this
  |
  = note: expected trait object `dyn Foo`
                   found struct `Bar`
  = help: `Bar` implements `Foo` so you could box the found value and coerce it to the trait object `Box<dyn Foo>`, you will have to change the expected type as well

error[E0620]: cast to unsized type: `Bar` as `dyn Foo`
 --> src/main.rs:7:23
  |
7 |     let f2: dyn Foo = Bar as dyn Foo;
  |                       ^^^^^^^^^^^^^^
  |
help: consider using a box or reference as appropriate
 --> src/main.rs:7:23
  |
7 |     let f2: dyn Foo = Bar as dyn Foo;
  |                       ^^^

error[E0277]: the size for values of type `dyn Foo` cannot be known at compilation time
 --> src/main.rs:6:9
  |
6 |     let f1: dyn Foo = Bar;
  |         ^^ doesn't have a size known at compile-time
  |
  = help: the trait `Sized` is not implemented for `dyn Foo`
  = note: all local variables must have a statically known size
  = help: unsized locals are gated as an unstable feature
help: consider borrowing here
  |
6 |     let f1: &dyn Foo = Bar;
  |             +

A

dyn Trait
是一种动态类型,表示实现该
Trait
的任何潜在具体类型。由于它代表各种可能不同大小的类型,因此它本身没有固定的大小。这称为 动态调整大小的类型 (DST)。

因为它们没有固定的大小,所以我们可以放置它们的位置受到限制。特别是 DST 不能存储在变量中;如果存储在结构中,它会使该结构成为 DST,因此也不能存储在变量中。有一个 unsized locals RFC 可能在未来使其成为可能,但现在它的命运尚不清楚。

旁注:您仍然可以将变量引用为动态特征,但这是因为变量仍然是已知的具体类型,即使特征对象动态访问它:

fn main() {
    let b = Bar;
    let f: &dyn Foo = &b;
}

因此,为了使用 DST,需要一些间接的方法;该值必须存储在其他地方,并且只能通过引用或智能指针(例如

Box
)来引用(
Rc
Arc
,也可以)。


技术上无关,但无论如何值得一提:对特征对象的引用和智能指针是“胖”的。这意味着它们实际上存储两个指针:一个指向数据,另一个指向映射到与该特征实现关联的特征函数的 v 表。请参阅什么是“胖指针”?了解更多信息。

rust traits type-traits trait-objects
1个回答
0
投票
© www.soinside.com 2019 - 2024. All rights reserved.