
Структуры данных:
Типы данных и ячейки памяти, определенные с помощью ключевых слов.
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, мы не перечисляем их здесь.