Типы
Каждая переменная, элемент и значение в программе Rust имеет тип. Тип значения определяет интерпретацию памяти, содержащей его, и операции, которые могут быть выполнены над значением.
Встроенные типы тесно интегрированы в язык нетривиальными способами, которые невозможно эмулировать в пользовательских типах.
Пользовательские типы имеют ограниченные возможности.
Список типов:
- Примитивные типы:
- Логический —
bool - Числовые — целочисленные и с плавающей запятой
- Текстовые —
charиstr - Never —
!— тип без значений
- Логический —
- Последовательные типы:
- Пользовательские типы:
- Функциональные типы:
- Указательные типы:
- Трейт-типы:
Выражения типов
Syntax
Type →
TypeNoBounds
| ImplTraitType
| TraitObjectType
TypeNoBounds →
ParenthesizedType
| ImplTraitTypeOneBound
| TraitObjectTypeOneBound
| TypePath
| TupleType
| NeverType
| RawPointerType
| ReferenceType
| ArrayType
| SliceType
| InferredType
| QualifiedPathInType
| BareFunctionType
| MacroInvocation
Выражение типа, как определено в грамматическом правиле Type выше, — это синтаксис для ссылки на тип. Оно может ссылаться на:
- Пути типов, которые могут ссылаться на:
- Примитивные типы (логический, числовые, текстовые).
- Пути к элементу (структура, перечисление, объединение, псевдоним типа, трейт).
- Путь
Self, гдеSelf— реализующий тип. - Обобщённые параметры типов.
- Указательные типы (ссылка, необработанный указатель, указатель на функцию).
- Выводимый тип, который просит компилятор определить тип.
- Круглые скобки, которые используются для устранения неоднозначности.
- Трейт-типы: Трейт-объекты и impl trait.
- Макросы, которые раскрываются в выражение типа.
Типы в круглых скобках
Syntax
ParenthesizedType → ( Type )
В некоторых ситуациях комбинация типов может быть неоднозначной. Используйте круглые скобки
вокруг типа, чтобы избежать неоднозначности. Например, оператор + для границ типов внутри ссылочного типа неясен, где
применяется граница, поэтому использование круглых скобок обязательно. Грамматические правила, которые
требуют этого устранения неоднозначности, используют правило TypeNoBounds вместо
Type.
#![allow(unused)] fn main() { use std::any::Any; type T<'a> = &'a (dyn Any + Send); }
Рекурсивные типы
Номинальные типы — структуры, перечисления и объединения — могут быть
рекурсивными. То есть, каждый вариант enum или поле struct или union может
ссылаться, прямо или косвенно, на охватывающий тип enum или struct
сам.
Такая рекурсия имеет ограничения:
- Рекурсивные типы должны включать номинальный тип в рекурсии (не просто псевдонимы типов или другие структурные типы, такие как массивы или кортежи). Так что
type Rec = &'static [Rec]не разрешено. - Размер рекурсивного типа должен быть конечным; другими словами, рекурсивные поля типа должны быть указательными типами.
Пример рекурсивного типа и его использования:
#![allow(unused)] fn main() { enum List<T> { Nil, Cons(T, Box<List<T>>) } let a: List<i32> = List::Cons(7, Box::new(List::Cons(13, Box::new(List::Nil)))); }