Структуры данных:
Типы данных и ячейки памяти, определенные с помощью ключевых слов.
struct S {}
- определение структуры с именованными полями.
struct S { x: T }
- определение структуры с именованным полем X типа T.struct S (T);
- определение структуры «tupled» с нумерованным полем .0 типа T.struct S;
- определение структуры блока NOM нулевого размера. Не занимает места, оптимизировано.
enum E {}
- определение перечисления, с алгебраическими типами данных, помещенных в объединение.
enum E { A, B
(), C{} }
- опрределяет варианты перечисления; может быть unit-A, tuple-B() и структурноподобным C{}.enum E { A = 1 }
- если варианты являются только единичными, допустимы дискриминантные значения, например, для FFI.enum E {}
- варианты enum неопределены, ссылка не может быть создана, это ‘never’.
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]
- специальная ссылка на фрагмент, содержащая (адрес, количество).&str
- специальная ссылка на фрагмент строки, которая содержит (адрес, количество байтов).&mut S
- исключительная ссылка на возможность изменения (&mut [S], & mut dyn S,…).&dyn T
- ссылка на объект специального контейнера, содержащая (адрес, таблицу).
&s
- совместное заимствование (например, адрес, длина, таблица,… это s как 0x1234).
&mut s
- исключительное заимствование, допускающее возможность изменения.
*const S
- неизменяемый тип необработанного указателя без безопасности памяти.
*mut S
- изменяемый тип необработанного указателя без безопасности памяти.&raw const s
- создаёт необработанный указатель без перехода через ссылку; ptr:addr_of!().&raw mut s
- то же самое, но изменяемое. Raw ptrs. необходимы для неориентированных упакованных полей.
ref s
- привязывает по ссылке, делает привязку ссылочным типом.
let ref r = s;
- эквивалентно r = &s.let S { ref mut x } = s;
- изменяемая ссылка (let x = &mut s.x), сокращенная деструктивная версия.
*r
- ссылка r для доступа к значению, на которое указывает.
*r = s;
- если r является изменяемой ссылкой, перемещает или копирует s в r.s = *r;
- делает s копией любых r ссылок, если это тип имеет Copy.s = *r;
- не будет работать, если *r не имеет Copy, так как это переместится и будет пустое значение.s = *my_box;
- особый случай для Box, который также может перемещать содержимое, не являющееся копией.
'a
- параметр времени жизни, длительность потока в статическом анализе.
&'a S
- то же самое, но разрешает изменение содержимого адреса.struct S<'a> {}
- сигнализирует, что S будет содержать адрес с временем жизни ‘a. Создать S разрешает ‘a.trait T<'a> {}
- сигнализирует, что любой S, которые подразумевают T для S, может содержать адрес.fn f<'a>(t: &'a T)
- сигнализирует, что эта функция обрабатывает некоторый адрес. Решение принимает ‘a.'static
- специальное время жизни, продолжающееся все время выполнения программы.
Функции и поведение
Определяет единицы кода и их абстракции.
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.
fn f() -> S {}
- то же самое, возвращая значение типа S.fn f(&self) {}
- определяет метод, например, в пределах impl S {}.
struct S
(T);
- определяет функцию конструктора fn S(x: T) -> S.
const fn f() {}
- константа fn, используемая во время компиляции, например, const X: u32 = f (Y).
async fn f() {}
- асинхронная функция, делает возврат из impl Future.
async fn f() -> S {}
- то же самое, но выполнить функцию f и вернуть impl Future <Output = S>.async { x }
- Используйте функцию, чтобы сделать {x} impl Future<Output = X>.
fn() -> S
- указатель функции, адрес хранения в памяти вызываемого устройства.
Fn() -> S
- вызываемая trait (также FnMut, FnOnce), реализованна закрытиями функций…
|| {}
- функция замыкания.
|x| {}
- замыкание, принимающее один аргумент с именем x, тело является блочным выражением.|x| x + x
- то же самое, без блочного выражения; может состоять только из одного выражения.move |x| x + y
- перемещает значение в замыкание в его собственность; то есть Y передается в замыкание.return || true
- замыкания иногда выглядят как логические OR (здесь: вернуть замыкание).
unsafe
- если вам нравится отладка; небезопасный код.
unsafe fn f() {}
- означает «вызов может вызвать небезопасную функцию, ВЫ должны проверить ее требования».unsafe trait T {}
- означает “небезопасный impl. Т может вызывать ошибку; исполнитель должен проверить “.unsafe { f(); }
- гарантии компилятору «Я проверил требования, поверь мне».unsafe impl T for S {}
- гарантии S, хорошо себя ведет T; люди могут безопасно использовать T на S.
Поток управления
Управление выполнением в функции
while x {}
- цикл, выполняется, пока выражение x имеет значение true.
loop {}
- бесконечный цикл до break. Может давать значение с break x.
for x in collection {}
- синтаксический сахар цикл по итератору.
collection.into_iter()
- преобразует любой тип в соответствующий итератор.iterator.next()
- перебирает итератор, x = next() до исчерпания (первый None).
if x {} else {}
- Условная ветвь, если выражение имеет значение true.
'label: {}
- метка блока, может использоваться для выхода из этого блока.
'label: loop {}
- аналогичная метка цикла, полезна для управления потоком во вложенных циклах.
break
- Разорвать выражение для выхода из блока или цикла.
break 'label x
- переходит из блока или цикла на метку с именем «label» и возращает значение x.break 'label
- то же самое, но не ни чего не возврвщвет.break x
- установливает значение x при выходе из самого внутреннего цикла (только в реальном цикле).
continue
- продолжает выполнение следующей итерации этого цикла.
continue 'label
- то же самое, но вместо этого цикла, переходит в верхний цикл, помеченный «label».
x?
- Если x равно Err или None, возвращает значение из функции или метода.
x.await
- Синтаксический сахар, чтобы получить future, poll, yield. Работает только в асинхронном режиме.
x.into_future()
- преобразует любой тип IntoFuture в future.future.poll()
- при Future выполняет poll() и поток yield, если Poll::Pending.
return x
- возвращение из функции. Более идиоматичным является завершение выражением.
{ return }
- выход из функции.|| { return }
- выход из замыкания.async { return }
- выход из асинхронной функции.
f()
- вызывает f (например, функцию, замыкание, указатель функции, Fn,…).
x.f()
- вызов метода, принимает self, &self,… в качестве первого аргумента.
X::f(x)
- аналогично x.f(). Только impl Copy для X {}, f можно вызвать только один раз.X::f(&x)
- аналогично x.f().X::f(&mut x)
- аналогично x.f().S::f(&x)
- то же, что и x.f(), если X дерефируется в S, т.е. x.f() находит методы S.T::f(&x)
- аналогично x.f(), если X impl T, т.е. x.f() находит методы T, если в области видимости.
X::f()
- вызов связанной функцию, например, X::new().
<X as T>::f()
- вызывает trait метод T::f(), реализованный для X.
Организационный код
Сегментирование проектов на более мелкие единицы и минимизирование зависимостей.
mod m {}
- определяет модуль, получает определение изнутри {}.
mod m;
- определяет модуль, получает определение из m.rs или m/mod.rs.
a::b
- путь к пространству имен к элементу b в пределах (mod, enum,…).
::b
- поиск b в корне модуля или внешней прелюдии; глобальный путь.crate::b
- поиск b в корне.self::b
- поиск b в текущем модуле.super::b
- поиск b в родительском модуле.
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.
pub(crate) T
- виден в текущем модуле.pub(super) T
- виден в родительском модуле.pub(self) T
- виден в текущем модуле (по умолчанию, как и без pub).pub(in a::b) T
- виден у предка a::b.
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) {}.
&self
- то же самое, но относится к себе как к заимствованию, будет равно f(self: &Self).&mut self
- то же, но заимствование мутабельно, будет равен f(self: &mut Self).self: Box<Self>
- произвольный самостоятельный тип, добавление методов к интеллектуальным указателям (my_box.f_of_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 или более раз в макросах на примере.
$(x),?
- то же самое, но ноль или один раз.$(x),+
- то же самое, но один или несколько раз.$(x)<<+
- также принимаются сепараторы, отличные от.
Паттерн Match
Конструкции в выражениях соответствия или разрешения или параметрах функции.
match m {}
- сопоставление шаблонов, используются команды match arms, из таблицы ниже.
let S(x) = get();
- аналогично таблице ниже.
let S { x } = s;
- x будет привязан к значению s.x.let (_, b, _) = abc;
- b будет привязан к значению abc.1.let (a, ..) = abc;
- игнорировать остальное.let (.., a, b) = (1, 2);
- привязки имеют приоритет над остальными, здесь a равно 1, b равно 2.let s @ S { x } = get();
- привязка s к S при привязке x к s.x, привязка шаблона.let w @ t @ f = get();
- сохраняет 3 копии результата get() в каждой w, t, f.let (|x| x) = get();
- не замыкание, то же, что и let 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 { x, y } => {}
- то же самое, но коротко с s.x и s.y, связанны как x и y соответственно.
S { .. } => {}
- шаблон структуры с любыми значениями.
D => {}
- шаблон варианта перечисления E::D, если D используется.
D => {}
- шаблон что угодно, связать D; возможно, ложный вариант E::D, если D не используется.
_ => {}
- шаблон «все остальное».
0 | 1 => {}
- альтернативные патерны.
E::A | E::Z => {}
- то же самое, но на вариантах перечисления.E::C {x} | E::D {x} => {}
- то же самое, но использовать x, если он есть у всех вариантов.Some(A | B) => {}
- то же самое, может также совпадать с глубоко вложенными альтернативами.|x| x => {}
- паттерн, ведущий | игнорируется, используется только x | x, следовательно x.
(a, 0) => {}
- шаблон кортеж с любым значением для а и 0.
[a, 0] => {}
- шаблон среза, соответствует массиву с любым значением для a и 0.
[1, ..] => {}
- шаблон массив, начинающийся с 1, дальше любое значение.[1, .., 5] => {}
- образец массив, начиная с 1, заканчивая 5.[1, x @ .., 5] => {}
- то же самое, но также привязать x к срезу, представляющему середину.[a, x @ .., b] => {}
- то же самое, но соответствует любому первому, последнему, как a, b соответственно.
1 .. 3 => {}
- шаблон диапазона, здесь соответствует 1 и 2.
1 ..= 3 => {}
- шаблон диапазона, соответствует 1, 2 и 3.1 .. => {}
- шаблон диапазона, совпадающий с 1 и любым большим числом.
x @ 1..=5 => {}
- шаблон соответствует x; привязка шаблона, здесь x будет 1, 2,… или 5.
Err(x @ Error {..}) => {}
- работает вложенно, здесь x привязывается к Error.
S { x } if x > 10 => {}
- защита соответствия шаблона, условие также должно быть true.
Дженерики и ограничения
Дженерики сочетаются с конструкторами типов, traits и функциями, что дает пользователям больше гибкости.
struct S<T> …
- универсальный тип с параметром типа (T здесь является именем типа).
S<T> where T: R
- trait типы допускаются T, T имеет свойство R; R должно быть в trait.
where T: R, P: S
- типы trait, здесь один для T и один для P.where T: R, S
- ошибка компиляции. Вероятно, необходимо создать составную привязку R + S см. ниже.where T: R + S
- trait типы T должны соответствовать R и S.where T: R + 'a
- то же самое, но со временем жизни. Т должен выполнять R, если Т имеет время жизни ‘а.where T: ?Sized
- отказаться от предварительно определенной границы trait, это размер.where T: 'a
- ограничение время жизни типа; если у T есть ссылки, они должны пережить ‘a.where T: 'static
- то же самое; не означает, что значение t будет жить в static.where 'b: 'a
- время жизни ‘b должно быть по крайней мере столько сколько и ‘a.where u8: R<T>
- позволяет делать условные операторы с участием других типов.
S<T: R>
- короткая запись, почти такая же, как и выше.
S<const N: usize>
- generic const; значение типа S может предоставить константу N.
S<10>
- при использовании в качестве примитивных значений может быть указан предел значения.S<{5+5}>
- выражения должны быть заключены в фигурные скобки.
S<T = R>
- параметры по умолчанию; делает S немного проще в использовании, но сохраняет его гибкость.
S<const N: u8 = 0>
- параметр по умолчанию для констант; например, в f(x: S) {} параметр N равен 0.S<T = u8>
- параметр по умолчанию для типов, например, в f(x: S) {} параметр T - u8.
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 в течение всего срока службы.
type X = R;
- задать связанный тип в пределах impl T for S {type X = R;}.type X<G> = R<G>;
- то же самое для GAT, например, impl T for S {type X<G> = Vec<G>;}.
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.
fn f() where Self: Sized;
- с помощью параметра размера можно отключить параметр f от параметра dyn T trait объекта vtable, включив параметр trait obj.fn f() where Self: R {}
- другие R полезные методы.
Другие выражения
Реальные типы и trait, абстрактные над чем-то, с периодом жизни.
for<'a>
- маркер для более дальних границ периода жизни.
trait T: for<'a> R<'a> {}
- любая S, которая предполагает Т, также должна будет выполнять R в течение любого срока службы.
fn(&'a u8)
- тип указателя функции, содержащий fn, вызываемый с определенным временем жизни «a».
for<'a> fn(&'a u8)
- ранжированный тип, содержащий fn, вызываемый с любым lt.; подтип выше см.
fn(&'_ u8)
- то же самое; автоматически расширяется до типа для <‘a> fn(&‘a u8).fn(&u8)
- то же самое; автоматически расширяется до типа для <‘a> fn(&‘a u8).
dyn for<'a> Fn(&'a u8)
- тип с более высоким рангом (признак-объект), работает как fn выше.
dyn Fn(&'_ u8)
- то же самое; автоматическое расширение до типа dyn for<‘a> Fn(&‘a u8).dyn Fn(&u8)
- то же самое; автоматическое расширение до типа dyn for<‘a> Fn(&‘a u8).
impl<'a> T for fn(&'a u8) {}
- для функции указатель, где вызов принимает определенные lt. ‘a, impl trait Т.
impl T for for<'a> fn(&'a u8) {}
- для функции указатель, где вызов принимает любой lt., impl trait Т.
impl T for fn(&u8) {}
- то же, короткая версия.
Строки и символы
У Rust есть несколько способов создания строк.
"..."
- строковый литерал, UTF-8.
"\n\r\t\0\\"
- ескейп символы, например, «\n» переход на новую строку."\x36"
- ASCII. До 7f, например, «\x36» станет 6."\u{7fff}"
- юникод. До 6 цифр, например, «\u {7fff} »становится 翿.
r"..."
- литерал необработанной строки, UTF-8, не интерпретирует ескейп символы.
r#"..."#
- строковый литерал, UTF-8, но может содержать символы “. Количество символов # может варьироваться.
b"..."
- строковый литерал байта; создает последовательность ASCII [u8], а не строку.
br"..."
, br#"..."#
- строковый литерал необработанного байта, ASCII [u8], комбинация вышеперечисленного.
'🦀'
- символьный литерал, фиксированный 4-байтовый юникод «char».
b'x'
- литерал байта ASCII, один байт u8.
Документация
Отладчики невидят его. Избегайте ошибок с этим странным трюком.
///
- комментарий в документе внешней линии, используйте их для типов, traits, функций,…
//!
- комментарий в документе внутренней строки, в основном используемый в начале файла для модуля документов.
//
- комментарий строки, используйте для документирования кода или внутренних устройств.
/* … */
- блочный комментарий.
/** … */
- комментарий в документе внешнего блока.
/*! … */
- комментарий в документе внутреннего блока.
Разное
Эти сигилы не подходили ни к одной другой категории, но, тем не менее, хорошо это знать.
!
- всегда пустой never тип.
fn f() -> ! {}
- функция, которая никогда не возвращается с любым типом, например, let x: u8 = f();fn f() -> Result<(), !> {}
- функция, которая должна возвращать результат, но сигнализирует о том, что она никогда не сможет вернуть ошибку.fn f(x: !) {}
- функция, которая существует, но не может быть вызвана. Не очень полезно.
_
- неименованная подстановочная переменная, например, | x, _| {}.
let _ = x;
- неназванное назначение - no-op, не перемещается из области x или не сохраняет область!_ = x;
- можно присвоить _ все, что угодно, без разрешения, т.е. _ = ignore_error();
_x
- привязка к переменной явно помечена как неиспользуемая.
1_234_567
- числовой разделитель для наглядности.
1_u8
- спецификатор типа для числовых литералов (также i8, u16,…).
0xBEEF
, 0o777
, 0b1001
- шестнадцатеричные (0x), восьмеричные (0o) и двоичные (0b) целочисленные литералы.
r#foo
- необработанный идентификатор для совместимости версий.
x;
- оператор окончания выражения.
Общие операторы
Rust поддерживает большинство операторов (+, *,%, =, =,…), включая перегрузку. Поскольку они ведут себя также в Rust, мы не перечисляем их здесь.