В руководстве Rust Edition говорится, что в Rust 1.2 дополнительные типы контейнеров поддерживают типы объектов. Он привел пример Rc<T>
, но не дал полного списка. Какие еще контейнеры поддерживают трейт-объекты в Rust 1.2+?
Какие контейнеры Rust 1.2 поддерживают трейт-объекты?
Ответы (1)
Контейнеры, поддерживающие трейт-объекты, — это контейнеры с привязкой ?Sized
. на их тип контейнера.
По умолчанию с дженериками все типы неявно Sized
, так как это то, что вам нужно большую часть времени, и добавление Sized
почти к каждому дженерику будет раздражать. Это поведение отличается от других трейтов, и его можно избежать, добавив границу ?Sized
.
struct Foo<T>; // implicit `T: Sized` bound. T cannot be a trait object.
struct Bat<T: ?Sized>; // T can be a trait object.
Вы можете увидеть в репозитории, что Rc
действительно использовался для объявлен pub struct Rc<T>
и позже изменен на pub struct Rc<T: ?Sized>
. GitHub перечисляет это изменение как часть Rust 1.1, но я предполагаю, что нам пришлось ждать 1.2, чтобы получить его в стабильной версии.
Другие контейнеры, которые работают с типаж-объектами, — это Box
, Arc
, Cell
и все подобные этим умным указателям.
Контейнеры, которые не работают с типаж-объектами, — это Vec
, HashMap
и обычно контейнеры, в которых может храниться более одного экземпляра (коллекции). Это связано с тем, что 2 экземпляра одного и того же типаж-объекта могут иметь разные размеры (если они имеют разный конкретный тип), а коллекции обычно постоянно хранят элементы, требуя постоянного размера.
Box<dyn Trait>
трейт-объектом, и это можно было бы поместить в Vec
.
- person Shepmaster; 05.07.2019