Какие контейнеры Rust 1.2 поддерживают трейт-объекты?

В руководстве Rust Edition говорится, что в Rust 1.2 дополнительные типы контейнеров поддерживают типы объектов. Он привел пример Rc<T>, но не дал полного списка. Какие еще контейнеры поддерживают трейт-объекты в Rust 1.2+?


person user102008    schedule 04.07.2019    source источник


Ответы (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 экземпляра одного и того же типаж-объекта могут иметь разные размеры (если они имеют разный конкретный тип), а коллекции обычно постоянно хранят элементы, требуя постоянного размера.

person mcarton    schedule 04.07.2019
comment
Вероятно, здесь стоит уточнить использование типаж-объекта. Я думаю, что большинство людей лениво назвали бы Box<dyn Trait> трейт-объектом, и это можно было бы поместить в Vec. - person Shepmaster; 05.07.2019