Cómo obtener un & dyn T de un Box <dyn T> [duplicado]
Estoy tratando de obtener un &dyn T
de a Box<dyn T>
, como en el siguiente ejemplo. Sin embargo, no se compila.
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)
El mensaje de error es
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`
Está claro que puede obtener &T
un Box<T>
. No entiendo por qué no puede obtener un &dyn T
de a Box<dyn T>
.
Respuestas
Para obtener un &dyn T
de a Box<dyn T>
, use &*
:
let c: &dyn MyTrait = &*b;
Se *
usa para eliminar el cuadro en su contenido ( dyn MyTrait
) y luego &
se usa para obtenerlo como referencia.
Esta es también la forma "correcta" de obtener &Foo
un Box<Foo>
. La razón por la que &b
funciona con tipos concretos es porque el Derefrasgo permite &Box<T>
ser coaccionado para &T
:
Si T implementa Deref <Target = U>, y x es un valor de tipo T, entonces:
- Los valores de tipo & T se convierten en valores de tipo & U
La razón por la que no funciona para los objetos de rasgo es que &dyn MyTrait
podría ser válido &Box<...>
y la coerción no se intenta incluso si falla.