Перейти к содержанию

Выражения

Posted on:3 февраля 2023 г. at 20:32

Example Dynamic OG Image link

Структуры данных:

Типы данных и ячейки памяти, определенные с помощью ключевых слов.

struct S {} - определение структуры с именованными полями.

enum E {} - определение перечисления, с алгебраическими типами данных, помещенных в объединение.

union U {} - небезопасное C-образное соединение ссылки для совместимости FFI.

static X: T = T(); - глобальная переменная со статическим временем жизни, одна ячейка памяти.

const X: T = T(); - определяет константу, определяется как временная при использовании.

let x: T; - выделяет T байт на стеке, именнуется как x. Назначается один раз, не может изменяться.

let mut x: T; - выделяет T байт на стеке, именнуется как x. Допускают мутабельность и изменяемое заимствование.

x = y; - перемещает y в x, что делает y недействительным, если значение не является копируемым типом.

Создание структур данных и доступ к ним; и некоторые типы.

S { x: y } - создаёт структуру S{} или использует перечисление E::S{} с полем x, равным значению y.

S { x } - то же самое, но использует локальную переменную x для поля x.

S { ..s } - заполняет оставшиеся поля из s, полезно с помощью Default::default().

S { 0: x } - как и S(x) ниже, но задается полем .0 с синтаксисом struct.

S​ (x) - создаёт структуру S(T) или использует перечисление E::S(), в поле .0 которого установлено значение x.

S - если S - блочная структура то S; или использует enum E::S создаёт значение S.

E::C { x: y } - создаёт вариант перечисления C. Другие методы, описанные выше, также работают.

() - пустой кортеж, как литерал, так и тип, он же блок.

(x) - выражение в скобках.

(x,) - одноэлементное выражение кортежа.

(S,) - тип одноэлементного кортежа.

[S] - тип массива неопределенной длины, т.е. фрагмент. Не может работать в стеке.

[S; n] - Массив фиксированной длины n содержащий элементы типа S.

[x; n] - экземпляр ссылки массива (выражение) с n копиями в x.

[x, y] - экземпляр массива с заданными элементами x и y.

x[0] - Индексация коллекции, здесь в квадратных скобках usize. Реализуется с Index, IndexMut.

x[..] - То же самое, через диапазон (это полный диапазон).

a..b - создаёт диапазон, например, 1..3 содержит 1, 2.

..b - диапазон без начальной точки.

..=b - включающий b диапазон без начальной точки.

a..=b - включающий b диапазон, 1..=3 означает 1, 2, 3.

a.. - диапазон без конечной точки.

.. - полный диапазон, обычно означает всю коллекцию.

s.x - доступ к именованному полю, ссылка может попытаться выполнить команду Deref, если x не является частью типа S.

s.0 - пронумерованный доступ к полю, используемый для кортежей S(T).

Ссылки и указатели

Предоставление доступа к памяти.

&S - общая ссылка (тип; пространство для хранения любых &s).

&s - совместное заимствование (например, адрес, длина, таблица,… это s как 0x1234).

*const S - неизменяемый тип необработанного указателя без безопасности памяти.

ref s - привязывает по ссылке, делает привязку ссылочным типом.

*r - ссылка r для доступа к значению, на которое указывает.

'a - параметр времени жизни, длительность потока в статическом анализе.

Функции и поведение

Определяет единицы кода и их абстракции.

trait T {} - определяет trait; Общие типы поведения BK EX REF могут соответствовать.

trait T : R {} - T - subtrait для supertrait R. Любая S должна иметь impl R, прежде чем она сможет иметь impl T.

impl S {} - реализация функциональных возможностей для типа S, например, методов.

impl T for S {} - реализация trait Т для типа S; указывает, как именно S действует, в Т.

impl !T for S {} - отключает производную trait T для типа S.

fn f() {} - определяет функцию или метод внутри impl.

struct S ​(T); - определяет функцию конструктора fn S(x: T) -> S.

const fn f() {} - константа fn, используемая во время компиляции, например, const X: u32 = f (Y).

async fn f() {} - асинхронная функция, делает возврат из impl Future.

fn() -> S - указатель функции, адрес хранения в памяти вызываемого устройства.

Fn() -> S - вызываемая trait (также FnMut, FnOnce), реализованна закрытиями функций…

|| {} - функция замыкания.

unsafe - если вам нравится отладка; небезопасный код.

Поток управления

Управление выполнением в функции

while x {} - цикл, выполняется, пока выражение x имеет значение true.

loop {} - бесконечный цикл до break. Может давать значение с break x.

for x in collection {} - синтаксический сахар цикл по итератору.

if x {} else {} - Условная ветвь, если выражение имеет значение true.

'label: {} - метка блока, может использоваться для выхода из этого блока.

'label: loop {} - аналогичная метка цикла, полезна для управления потоком во вложенных циклах.

break - Разорвать выражение для выхода из блока или цикла.

continue - продолжает выполнение следующей итерации этого цикла.

continue 'label - то же самое, но вместо этого цикла, переходит в верхний цикл, помеченный «label».

x? - Если x равно Err или None, возвращает значение из функции или метода.

x.await - Синтаксический сахар, чтобы получить future, poll, yield. Работает только в асинхронном режиме.

return x - возвращение из функции. Более идиоматичным является завершение выражением.

f() - вызывает f (например, функцию, замыкание, указатель функции, Fn,…).

x.f() - вызов метода, принимает self, &self,… в качестве первого аргумента.

X::f() - вызов связанной функцию, например, X::new().

Организационный код

Сегментирование проектов на более мелкие единицы и минимизирование зависимостей.

mod m {} - определяет модуль, получает определение изнутри {}.

mod m; - определяет модуль, получает определение из m.rs или m/mod.rs.

a::b - путь к пространству имен к элементу b в пределах (mod, enum,…).

use a::b; - использовать непосредственно в этом модуле.

use a::{b, c}; - то же самое, но включить b и c в модуль.

use a::b as x; - включить b в модуль, но по имени x, например, использовать std::error::Error as E.

use a::b as _; - приводит b анонимно в модуль, полезно для trait с конфликтующими именами.

use a::*; - включает все из a, рекомендуется, если a является какой-то прелюдией.

pub use a::b; - включает a::b в модуль для реэкспорта.

pub T - публичное значение, родительский путь является общедоступным для T.

extern crate a; - объявить зависимость от внешнего модуля; просто используйте a::b.

extern "C" {} - объявить внешние зависимости и ABI (например, «C») из FFI.

extern "C" fn f() {} - определить функцию для экспорта с ABI (например, «C») в FFI.

Псевдонимы и составные части типа

Краткие имена типов и методы преобразования одного типа в другой.

type T = S; - создает псевдоним типа, т.е. другое имя для S.

Self - псевдоним типа для реализующего типа, например, fn new() -> Self.

self - Объект метода в fn f(self) {}, например, сродни fn f(self: Self) {}.

<S as T> - определяет тип S как trait T, например, <S as T >::f().

a::b as c - при использовании импортирует b как c, например, use a::b as c.

x as u32 - примитивное преобразование типа, может усекаться и быть немного неожиданным.

Макросы и атрибуты

Конструкции генерации кода расширяются до фактической компиляции.

m!() - вызов макроса, также m!{}, m![] (в зависимости от макроса).

#[attr] - внешний атрибут, аннотирование следующего элемента.

#![attr] - внутренний атрибут, аннотирующий верхний окружающий элемент.

$x:ty - захват макросов,:… фрагмент определяет, что разрешено для $x.

$x - подстановка макросов, например, использует захваченный $x:ty сверху.

$(x),* - повторение макросов 0 или более раз в макросах на примере.

Паттерн Match

Конструкции в выражениях соответствия или разрешения или параметрах функции.

match m {} - сопоставление шаблонов, используются команды match arms, из таблицы ниже.

let S(x) = get(); - аналогично таблице ниже.

let Some(x) = get(); - не будет работать, если шаблон будет опровергнут, используйте let else или if let вместо этого.

let Some(x) = get() else {}; - делать, если возможно, if not else {}, обычно break, return, panic!,…

if let Some(x) = get() {} - ветвь, если шаблон может быть назначен (например, вариант перечисления), синтаксический сахар.

while let Some(x) = get() {} - продолжает вызывать get() в цикле до тех пор, пока шаблон может быть назначен.

fn f(S { x }: S) - параметры функции также работают, здесь x привязана к s.x из f(s).

Совпадающие элементы шаблона в выражениях соответствия. Левую часть этого также можно найти в выражениях let.

E::A => {} - шаблон варианта перечисления A, совпадение шаблонов.

E::B ( .. ) => {} - шаблон варианта кортежа перечисления B, игнорирует любой индекс.

E::C { .. } => {} - шаблон варианта структуры перечисления C, игнорирует любое поле.

S { x: 0, y: 1 } => {} - шаблон структуры с определенными значениями (принимает только s.x 0 и s.y 1).

S { x: a, y: b } => {} - шаблон структуры с любыми значениями связывает s.x с a и s.y с b.

S { .. } => {} - шаблон структуры с любыми значениями.

D => {} - шаблон варианта перечисления E::D, если D используется.

D => {} - шаблон что угодно, связать D; возможно, ложный вариант E::D, если D не используется.

_ => {} - шаблон «все остальное».

0 | 1 => {} - альтернативные патерны.

(a, 0) => {} - шаблон кортеж с любым значением для а и 0.

[a, 0] => {} - шаблон среза, соответствует массиву с любым значением для a и 0.

1 .. 3 => {} - шаблон диапазона, здесь соответствует 1 и 2.

x @ 1..=5 => {} - шаблон соответствует x; привязка шаблона, здесь x будет 1, 2,… или 5.

S { x } if x > 10 => {} - защита соответствия шаблона, условие также должно быть true.

Дженерики и ограничения

Дженерики сочетаются с конструкторами типов, traits и функциями, что дает пользователям больше гибкости.

struct S<T> … - универсальный тип с параметром типа (T здесь является именем типа).

S<T> where T: R - trait типы допускаются T, T имеет свойство R; R должно быть в trait.

S<T: R> - короткая запись, почти такая же, как и выше.

S<const N: usize> - generic const; значение типа S может предоставить константу N.

S<T = R> - параметры по умолчанию; делает S немного проще в использовании, но сохраняет его гибкость.

S<'_> - предполагаемое анонимное время жизни; просит компилятор «разобраться», если это очевидно.

S<_> - анонимный тип, например let x: Vec<_> = iter.collect ().

S::<T> - значения типа, например, f::<u32>().

trait T<X> {} - дженерик X. Может иметь несколько impl T для S (по одному на X).

trait T { type X; } - определяет связанный тип X. Возможен только один impl T для S.

trait T { type X<G>; } - определяет универсальный связанный тип (GAT), например, X может быть универсальным Vec<>.

trait T { type X<'a>; } - определяет базовую модель GAT в течение всего срока службы.

impl<T> S<T> {} - реализует метод для любого T в S<T>, здесь T тип параметра.

impl S<T> {} - реализует метод для S<T>, здесь T специфический тип, например, u8.

fn f() -> impl T - экзистенциальные типы, возвращает неизвестное вызывающему S, который предполагает Т.

fn f(x: &impl T) - trait связанный через «impl traits», несколько похожий на fn f<S:T>(x: & S).

fn f(x: &dyn T) - вызов f посредством динамической вызова, f не будет создан для x.

fn f<X: T>(x: X) - универсальная функция над X, f будет создана («мономорфизирована») для каждого X.

fn f() where Self: R; - в trait T {} сделать f доступным только для типов, известных также как impl R.

Другие выражения

Реальные типы и trait, абстрактные над чем-то, с периодом жизни.

for<'a> - маркер для более дальних границ периода жизни.

fn(&'a u8) - тип указателя функции, содержащий fn, вызываемый с определенным временем жизни «a».

for<'a> fn(&'a u8) - ранжированный тип, содержащий fn, вызываемый с любым lt.; подтип выше см.

dyn for<'a> Fn(&'a u8) - тип с более высоким рангом (признак-объект), работает как fn выше.

impl<'a> T for fn(&'a u8) {} - для функции указатель, где вызов принимает определенные lt. ‘a, impl trait Т.

impl T for for<'a> fn(&'a u8) {} - для функции указатель, где вызов принимает любой lt., impl trait Т.

Строки и символы

У Rust есть несколько способов создания строк.

"..." - строковый литерал, UTF-8.

r"..." - литерал необработанной строки, UTF-8, не интерпретирует ескейп символы.

r#"..."# - строковый литерал, UTF-8, но может содержать символы “. Количество символов # может варьироваться.

b"..." - строковый литерал байта; создает последовательность ASCII [u8], а не строку.

br"...", br#"..."# - строковый литерал необработанного байта, ASCII [u8], комбинация вышеперечисленного.

'🦀' - символьный литерал, фиксированный 4-байтовый юникод «char».

b'x' - литерал байта ASCII, один байт u8.

Документация

Отладчики невидят его. Избегайте ошибок с этим странным трюком.

/// - комментарий в документе внешней линии, используйте их для типов, traits, функций,…

//! - комментарий в документе внутренней строки, в основном используемый в начале файла для модуля документов.

// - комментарий строки, используйте для документирования кода или внутренних устройств.

/* … */ - блочный комментарий.

/** … */ - комментарий в документе внешнего блока.

/*! … */ - комментарий в документе внутреннего блока.

Разное

Эти сигилы не подходили ни к одной другой категории, но, тем не менее, хорошо это знать.

! - всегда пустой never тип.

_ - неименованная подстановочная переменная, например, | x, _| {}.

_x - привязка к переменной явно помечена как неиспользуемая.

1_234_567 - числовой разделитель для наглядности.

1_u8 - спецификатор типа для числовых литералов (также i8, u16,…).

0xBEEF, 0o777, 0b1001 - шестнадцатеричные (0x), восьмеричные (0o) и двоичные (0b) целочисленные литералы.

r#foo - необработанный идентификатор для совместимости версий.

x; - оператор окончания выражения.

Общие операторы

Rust поддерживает большинство операторов (+, *,%, =, =,…), включая перегрузку. Поскольку они ведут себя также в Rust, мы не перечисляем их здесь.