Как получить & dyn T из коробки <dyn T> [дубликат]
Я пытаюсь получить &dyn T
от a Box<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`
Понятно, что получить a можно &T
из файла Box<T>
. Я не понимаю, почему вы не можете получить &dyn T
а Box<dyn T>
.
Ответы
Чтобы получить &dyn T
от a Box<dyn T>
, используйте &*
:
let c: &dyn MyTrait = &*b;
*
Используются для deref коробки в его содержание ( dyn MyTrait
) , а затем &
используются для получения его в качестве ссылки.
Это также «правильный» способ получить &Foo
от a Box<Foo>
. Причина , по которой &b
работает с конкретными типами потому , что Derefсвойство позволяет &Box<T>
быть принужден к &T
:
Если T реализует Deref <Target = U>, а x является значением типа T, то:
- Значения типа & T приводятся к значениям типа & U
Причина, по которой это не работает для объектов-признаков, заключается в том, что они &dyn MyTrait
могут быть действительными, &Box<...>
и принуждение не выполняется, даже если оно не выполняется.