如何从 Box<dyn T> 获取 &dyn T

4

我正在尝试从Box<dyn T>中获取一个&dyn T,就像下面的示例一样。然而,它无法编译。

trait MyTrait {
    
}

struct Foo;
impl MyTrait for Foo {}

fn main() {
    let b: Box<dyn MyTrait> = Box::new(Foo);
    let c: &dyn MyTrait = &b;
}

(https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=69c72904fbceae5b55470a878a441b7d)

错误信息如下:

error[E0277]: the trait bound `Box<dyn MyTrait>: MyTrait` is not satisfied
  --> src/main.rs:10:27
   |
10 |     let c: &dyn MyTrait = &b;
   |                           ^^ the trait `MyTrait` is not implemented for `Box<dyn MyTrait>`
   |
   = note: required for the cast to the object type `dyn MyTrait`

很明显,你可以从一个 Box<T> 获取一个 &T。我不理解为什么你不能从一个 Box<dyn T> 获取一个 &dyn T


可能与dyn T未被大小化,因此无法由标准指针表示有关。https://doc.rust-lang.org/nightly/std/boxed/index.html#memory-layout - sam
1个回答

8

Box<dyn T> 获得一个 &dyn T,使用 &*

let c: &dyn MyTrait = &*b;
*用于获取盒子内的内容(dyn MyTrait),&用于将其作为引用获取。这也是从Box<Foo>中获取&Foo的“正确”方法。 &b 适用于具体类型的原因是Deref trait允许将&Box<T>转换为&T

如果 T 实现了 Deref<Target = U>,并且 x 是类型为 T 的值,则:

  • 类型为&T的值被强制转换为类型为&U的值
对于特征对象而言,它不起作用的原因是&dyn MyTrait可能对于&Box<...>有效,即使失败也不会尝试强制转换。

作为对&*b的替代方案,您可以使用b.as_ref() - pvillela

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接