Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Специальные типы и трейты

Определённые типы и трейты, существующие в стандартной библиотеке, известны компилятору Rust. Эта глава документирует специальные особенности этих типов и трейтов.

Box<T>

Box<T> имеет несколько специальных особенностей, которые Rust в настоящее время не позволяет для пользовательских типов.

  • Оператор разыменования для Box<T> создаёт место, из которого можно перемещать. Это означает, что оператор * и деструктор Box<T> встроены в язык.
  • Методы могут принимать Box<Self> в качестве получателя.
  • Трейт может быть реализован для Box<T> в том же крейте, что и T, что правила сирот запрещают для других обобщённых типов.

Rc<T>

Методы могут принимать Rc<Self> в качестве получателя.

Arc<T>

Методы могут принимать Arc<Self> в качестве получателя.

Pin<P>

Методы могут принимать Pin<P> в качестве получателя.

UnsafeCell<T>

std::cell::UnsafeCell<T> используется для внутренней изменяемости. Он гарантирует, что компилятор не выполняет оптимизации, которые некорректны для таких типов.

Он также гарантирует, что static элементы, которые имеют тип с внутренней изменяемостью, не размещаются в памяти, помеченной как только для чтения.

PhantomData<T>

std::marker::PhantomData<T> — это тип с нулевым размером и минимальным выравниванием, который считается владеющим T для целей ковариантности, проверки удаления и автотрейтов.

Трейты операторов

Трейты в std::ops и std::cmp используются для перегрузки операторов, индексных выражений и вызовов выражений.

Deref и DerefMut

Помимо перегрузки унарного оператора *, Deref и DerefMut также используются в разрешении методов и приведениях разыменования.

Drop

Трейт Drop предоставляет деструктор, который будет запущен, когда значение этого типа должно быть уничтожено.

Copy

Трейт Copy изменяет семантику типа, который его реализует.

Значения, тип которых реализует Copy, копируются при присваивании, а не перемещаются.

Copy может быть реализован только для типов, которые не реализуют Drop, и все поля которых Copy. Для перечислений это означает, что все поля всех вариантов должны быть Copy. Для объединений это означает, что все варианты должны быть Copy.

Copy реализуется компилятором для

  • Замыканий, которые не захватывают значений или захватывают только значения Copy типов

Clone

Трейт Clone является супертрейтом Copy, поэтому ему также нужны сгенерированные компилятором реализации.

Он реализуется компилятором для следующих типов:

  • Типов со встроенной реализацией Copy (см. выше)
  • Замыканий, которые захватывают только значения Clone типов или не захватывают значений из окружения

Send

Трейт Send указывает, что значение этого типа безопасно отправлять из одного потока в другой.

Sync

Трейт Sync указывает, что значением этого типа безопасно делиться между несколькими потоками.

Этот трейт должен быть реализован для всех типов, используемых в неизменяемых static элементах.

Termination

Трейт Termination указывает допустимые возвращаемые типы для главной функции и тестовых функций.

Автотрейты

Трейты Send, Sync, Unpin, UnwindSafe и RefUnwindSafe являются автотрейтами. Автотрейты имеют специальные свойства.

Если для автотрейта для данного типа не написана явная реализация или отрицательная реализация, то компилятор реализует его автоматически согласно следующим правилам:

  • &T, &mut T, *const T, *mut T, [T; n] и [T] реализуют трейт, если T делает это.
  • Типы функциональных элементов и указатели на функции автоматически реализуют трейт.
  • Структуры, перечисления, объединения и кортежи реализуют трейт, если все их поля делают это.
  • Замыкания реализуют трейт, если типы всех их захватов делают это. Замыкание, которое захватывает T по общей ссылке и U по значению, реализует любые автотрейты, которые реализуют и &T, и U.

Для обобщённых типов (считая встроенные типы выше обобщёнными над T), если доступна обобщённая реализация, то компилятор не реализует её автоматически для типов, которые могли бы использовать реализацию, но не удовлетворяют необходимым ограничениям трейтов. Например, стандартная библиотека реализует Send для всех &T, где TSync; это означает, что компилятор не будет реализовывать Send для &T, если TSend, но не Sync.

Автотрейты также могут иметь отрицательные реализации, показанные как impl !AutoTrait for T в документации стандартной библиотеки, которые переопределяют автоматические реализации. Например, *mut T имеет отрицательную реализацию Send, и поэтому *mut T не Send, даже если TSend. В настоящее время нет стабильного способа указывать дополнительные отрицательные реализации; они существуют только в стандартной библиотеке.

Автотрейты могут быть добавлены как дополнительное ограничение к любому трейт-объекту, даже хотя обычно разрешён только один трейт. Например, Box<dyn Debug + Send + UnwindSafe> является допустимым типом.

Sized

Трейт Sized указывает, что размер этого типа известен во время компиляции; то есть, это не динамически sized тип.

Параметры типов (кроме Self в трейтах) являются Sized по умолчанию, как и ассоциированные типы.

Sized всегда автоматически реализуется компилятором, а не элементами реализации.

Эти неявные ограничения Sized могут быть ослаблены с использованием специального ограничения ?Sized.