Операторы
Syntax
Statement →
;
| Item
| LetStatement
| ExpressionStatement
| OuterAttribute* MacroInvocationSemi
Оператор — это компонент блока, который в свою очередь является компонентом внешнего выражения или функции.
Rust имеет два вида операторов: операторы объявления и операторы выражений.
Операторы объявления
Оператор объявления — это оператор, который вводит одно или несколько имён в охватывающий блок операторов. Объявленные имена могут обозначать новые переменные или новые элементы.
Два вида операторов объявления — это объявления элементов и операторы let.
Объявления элементов
Оператор объявления элемента имеет синтаксическую форму, идентичную объявлению элемента внутри модуля.
Объявление элемента внутри блока операторов ограничивает его область видимости блоком, содержащим оператор. Элементу не даётся канонический путь, как и любым подэлементам, которые он может объявлять.
Исключением является то, что ассоциированные элементы, определённые реализациями, всё ещё доступны во внешних областях видимости, пока элемент и, если применимо, трейт доступны. В остальном это идентично по смыслу объявлению элемента внутри модуля.
Не происходит неявного захвата обобщённых параметров, параметров и локальных переменных содержащей функции.
Например, inner не может получить доступ к outer_var.
#![allow(unused)] fn main() { fn outer() { let outer_var = true; fn inner() { /* outer_var не в области видимости здесь */ } inner(); } }
Операторы let
Syntax
LetStatement →
OuterAttribute* let PatternNoTopAlt ( : Type )?
(
= Expression
| = Expressionexcept LazyBooleanExpression or end with a } else BlockExpression
)? ;
Оператор let вводит новый набор переменных, заданный паттерном.
Паттерн следует, опционально, за аннотацией типа, а затем либо заканчивается, либо следует за выражением инициализации плюс опциональный блок else.
Когда аннотация типа не дана, компилятор выведет тип или сообщит об ошибке, если недостаточно информации о типе для определённого вывода.
Любые переменные, введённые объявлением переменной, видны с точки объявления до конца охватывающей области видимости блока, за исключением случаев, когда они затенены другим объявлением переменной.
Если блок else отсутствует, паттерн должен быть неопровержимым.
Если блок else присутствует, паттерн может быть опровержимым.
Если паттерн не совпадает (это требует, чтобы он был опровержимым), выполняется блок else.
Блок else всегда должен расходиться (вычисляться в тип never).
#![allow(unused)] fn main() { let (mut v, w) = (vec![1, 2, 3], 42); // Привязки могут быть mut или const let Some(t) = v.pop() else { // Опровержимые паттерны требуют блока else panic!(); // Блок else должен расходиться }; let [u, v] = [v[0], v[1]] else { // Этот паттерн неопровержим, поэтому компилятор // предупредит, что блок else избыточен. panic!(); }; }
Операторы выражений
Syntax
ExpressionStatement →
ExpressionWithoutBlock ;
| ExpressionWithBlock ;?
Оператор выражения — это оператор, который вычисляет выражение и игнорирует его результат. Как правило, цель оператора выражения — вызвать эффекты вычисления его выражения.
Выражение, состоящее только из блочного выражения или выражения управления потоком, если используется в контексте, где разрешён оператор, может опускать завершающую точку с запятой. Это может вызвать неоднозначность между его разбором как самостоятельного оператора и как части другого выражения; в этом случае он разбирается как оператор.
Тип выражений ExpressionWithBlock при использовании в качестве операторов должен быть типом unit.
#![allow(unused)] fn main() { let mut v = vec![1, 2, 3]; v.pop(); // Игнорировать элемент, возвращённый из pop if v.is_empty() { v.push(5); } else { v.remove(0); } // Точка с запятой может быть опущена. [1]; // Отдельный оператор выражения, не индексное выражение. }
Когда завершающая точка с запятой опущена, результат должен быть типа ().
#![allow(unused)] fn main() { // плохо: тип блока i32, не () // Ошибка: ожидался `()` из-за типа возврата по умолчанию // if true { // 1 // } // хорошо: тип блока i32 if true { 1 } else { 2 }; }
Атрибуты на операторах
Операторы принимают внешние атрибуты.
Атрибуты, которые имеют смысл на операторе, — это cfg и атрибуты проверки линтов.