Rust (язык программирования)

Материал из Википедии — свободной энциклопедии
Перейти к навигации Перейти к поиску
Rust
Rust programming language black logo.svg
Семантика мультипарадигмальный: параллельное, функциональное, императивное, структурное программирование
Класс языка процедурный язык программирования[d], язык функционального программирования, мультипарадигмальный язык программирования, императивный язык программирования[d], язык системного программирования[d], свободное программное обеспечение и Компилируемый язык программирования
Тип исполнения компилируемый
Появился в 2010
Автор Грэйдон Хор, разработчики проекта Rust
Разработчик Mozilla[1] и Graydon Hoare[d][1][2]
Расширение файлов .rs, .rlib
Выпуск
Система типов статическая, строгая, с выводом типов, номинальная, линейная, опционально динамическая
Основные реализации: rustc
Испытал влияние Alef, C++, Camlp4, Common Lisp, Erlang, Haskell, Hermes, Limbo, Napier, Napier88, Newsqueak, NIL, Sather, OCaml, Standard ML, Cyclone, Scheme, Swift, C#, Ruby[4]
Повлиял на Swift, Crystal
Лицензия Apache License 2.0[5] и лицензия MIT[5]
ОС кроссплатформенность
Сайт rust-lang.org

Rust (англ. rustржавчина, произносится [rʌst] — раст) — мультипарадигмальный компилируемый язык программирования общего назначения, спонсируемый Mozilla Research, сочетающий парадигмы функционального и процедурного программирования с объектной системой, основанной на типажах, и с управлением памятью через понятие «владения» (систему аффинных типов[en][6], позволяющую обходиться без сборки мусора). Объектно-ориентированное программирование как таковое языком не поддерживается, но язык позволяет реализовать большинство понятий ООП при помощи других абстракций[7].

Ключевые особенности языка: безопасность, скорость и параллелизм. Rust пригоден для системного программирования, в частности, он рассматривается как перспективный язык для разработки ядер операционных систем[6]. Rust сопоставим по скорости и возможностям с C++, однако даёт большую безопасность при работе с памятью, что обеспечивается механизмами ограничения. Rust также направлен на достижение «абстракции с нулевой стоимостью»[8].

После нескольких лет активной разработки первая стабильная версия (1.0) вышла 15 мая 2015 года, после чего новые версии выходят раз в 6 недель[9]. Для версий языка, вышедших после 1.0, заявлена обратная совместимость[10].

Язык отчасти берёт своё название от грибов семейства ржавчинные (англ. rust fungi)[11].

История[править | править код]

  • Работа над языком была начата Грэйдоном Хором в 2006 году, в 2009[12] к разработке подключилась Mozilla, и в 2010 году язык был официально представлен на Mozilla Summit 2010[13]. Также в 2010 году разработка языка была переведена с использования компилятора, написанного на OCaml, на компилятор, написанный на Rust, с использованием LLVM в качестве back-end[14]. В следующем году он успешно скомпилировал сам себя[15].
  • Январь 2012 г.: выпуск альфа-версии (0.1) компилятора Rust[16].
  • Апрель 2013 г.: выпуск версии 0.6. Одновременно с этим, Mozilla объявила о присоединении к проекту Servo — браузерному движку нового поколения — компании Samsung, при активном участии которой код движка был портирован на ARM архитектуру[17].
  • Май 2015 г.: выпуск версии Rust 1.0. Программные интерфейсы и возможности языка подверглись значительной ревизии, после которой по умолчанию оставлены только полностью готовые к применению возможности, реализация которых не будет изменяться в дальнейшем. Все остальные функции переведены в разряд экспериментальных и вынесены из поставки по умолчанию.[18]
  • В 2016—2018 гг. в ежегодных опросах Stack Overflow Rust каждый раз занимает первое место в списке любимых языков[19] (в 2015 году — третье место[20]).

Обзор[править | править код]

Основной источник: [21]

Система типов[править | править код]

Особенности[править | править код]

Основные типы[править | править код]

В Rust все типы можно разделить на две основные группы:

  • Простые типы (типы постоянной длины, встроенные в сам язык): Числовой, Булев, Символ, Массив, Срез, Строковый срез, Кортеж, Ссылка, Указатель на функцию[25][26]. Из простых типов можно выделить «Машинные» типы (реализованные непосредственно в современных процессорах): Числовой, Булев, Символ.
  • Типы, предоставляемые стандартной библиотекой std (переменной длины): Вектор, Строка, Хеш-таблица и т. д.
Числовой
  • Целое (integer). i8, u8, i16, u16, i32, u32, i64, u64, i128, u128, а также isize и usize, имеющие размер указателя на данной платформе. u8 применяется для "байтовых" значений. Примеры значений: -5i8, 0x400_u16, 0o100i16, 20_922_789_888u64, b'*' (байтовый литерал), b'\x1b', 42 (тип этого значения будет выведен автоматически), 0xfff_fc00usize,
Булев (bool)
true, false.
Символ (char)
Тип, представляющий символ Unicode (внутреннее представление данных как u32). Примеры значений: '₽', '\n', '\x7f', '\u{CA0}',
Указатель на функцию (function pointer)
Объекты-функции имеют тип, определяемый их сигнатурой, т. е. параметрами и возвращаемым значением. Пример: let f: fn(i32) -> i32 = plus_one;
Ссылка
  • Ссылка (разделяемое заимствование - shared borrow) &T (разделяемая, не изменяемая, не владеющая ресурсом), вместо того, чтобы забирать владение ресурсом, она его заимствует. Имена, которые заимствуют что-то, не освобождают ресурс, когда они выходят из области видимости. Кроме того, имена-владельцы переходят в заимствованное состояние[27].
  • Ссылка изменяемая (изменяемое заимствование - mutable borrow) &mut T (не владеющая ресурсом). Позволяет изменять ресурс, который заимствуется.
Коллекция
  • Массив (array) [T; N] — последовательность элементов одного и того же типа, имеющая фиксированный размер. Примеры: [1, 2, 3], [true; 10000].
  • Вектор (vec, vector) Vec<T>  — это динамический, или расширяемый массив, реализованный в виде стандартного библиотечного типа Vec<T>. Примеры: vec![0; 10];, Vec::with_capacity(10)
  • Срез (slice, view) &[T]  — это ссылка (или «проекция») на другую структуру данных. Они полезны, когда нужно обеспечить безопасный, эффективный доступ к части массива без копирования. Пример: &a[1..4],
  • Кортеж (tuple) (T1, T2, T3, ...). Подобно структуре, содержит произвольное количество разнотипных полей, но поля безымянны, обращение к полям возможно по индексу (t.0, t.1). Кортежи — безымянные типы: кортежи с одинаковым количеством и типами полей являются совместимыми по типу. С помощью ключевого слова type можно задать псевдоним, который, однако, не задаёт нового типа. Пример: ("Age", 22), ("Europe",),
  • Кортеж нулевой длины ((); пустой кортеж) часто называют «единичным значением». Соответственно, тип такого значения  — «единичный тип». Если функция не возвращает значение, то считается, что она возвращает ().
  • Хеш-таблица ключ-значение (HashMap) HashMap<T1, T2> - это структура данных, реализующая интерфейс ассоциативного массива, а именно, она позволяет хранить пары (ключ, значение) и выполнять три операции: операцию добавления новой пары, операцию поиска и операцию удаления пары по ключу. Хеш-таблицы в Rust похожи на векторы, и хранят свои значения не по индексу, а по ключу. Пример: HashMap::new();
  • Хеш-таблица — множество (HashSet) HashSet<T> - множество уникальных значений типа T. Добавление и удаление элементов, а также поиск элементов происходит быстрее, чем в других коллекциях[каких?].
Строка
  • Строка (String) (имеет внутреннее представление данных в виде Vec<u8>) — тип, владеющий содержимым. String представляет собой строку, размещённую в куче. Эта строка расширяема, и она гарантированно является корректной последовательностью байтов с точки зрения UTF-8. String обычно создаётся путём преобразования из строкового среза с использованием метода to_string. Примеры: "строковый срез".to_string(), String::new().
  • «Строковый срез» (string slice, string literal) &str, &'static str. Частный случай среза. Строковые срезы имеют фиксированный размер и не могут быть изменены. Они представляют собой ссылку на последовательность байтов UTF-8. Пример: "строковый срез". &'static str - строка, введённая символами в коде самой программы, - тот же строковый срез, только статически размещённый (сохраняемый в скомпилированной программе).
    • «Сырой строковый срез» (или сырой строковый литерал), в котором не работают управляющие последовательности: r"\d{0,5}.*".
    • «Байтовая строка» &[u8] - строковый литерал с префиксом «b»: b"white".

Возможности объявления пользовательских (составных) типов[править | править код]

Структура (struct)
  • Структура Си-подобная. Пример: struct Color {red: u8, green: u8, blue: u8}
  • Структура-кортеж. Пример: struct Color (u8, u8, u8);
  • Структура — «единичное» значение. Пример: struct Electron;
Перечисление (enum)
Каждый вариант в перечислении в Rust может быть также связан с другими данными, благодаря чему перечисление называют также tagged union или типом-суммой. Синтаксис для объявления вариантов схож с синтаксисом для объявления структур: могут быть варианты без данных, варианты с именованными данными и варианты с безымянными данными:
  • Вариант с «единичным» значением: enum Day {Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday}
  • Вариант с конкретным значением: enum Foo {Bar = 123,}.
  • Вариант — структура (именованные данные): enum Message {Quit, Move { x: i32, y: i32 }}.
  • Вариант — кортежная структура (безымянные данные): enum Message {Quit, Size(i32)}.
Константа
  • const — постоянные. Живут в течение всего времени работы программы. А именно, у них вообще нет определённого адреса в памяти. Это потому, что они встраиваются (inline) в каждое место, где есть их использование,
  • static — значение с возможностью изменения, имеющее время жизни 'static. Похожи на постоянные, но статические значения не встраиваются в место их использования. Это значит, что каждое значение существует в единственном экземпляре, и у него есть определённый адрес.

При выборе следует отдавать предпочтение const, так как зачастую для константы не нужен конкретный адрес в памяти и const позволяет делать оптимизации вроде Свёртки констант[28].

Управление памятью[править | править код]

В Rust реализована «умная» модель памяти, поддерживающая эффективные структуры данных и безопасные шаблоны параллельного выполнения, а также полностью запрещающая некорректный доступ к памяти, который обычно является источником критических ошибок сегментации в других языках программирования. Отсутствие нулевых указателей; контроль за использованием неинициализированных и деинициализированных переменных; невозможность совместного использования разделяемых состояний несколькими задачами; статический анализ времени жизни указателей; проверка на выход за пределы массива (автоматически и всегда).

Модель памяти Rust можно охарактеризовать следующими терминами.

Move-семантика
По умолчанию объект «переносится» (move) новому владельцу при присваивании. При этом происходит простое побайтовое копирование (в случае оптимизации не происходит и этого), старая связка при этом становится недействительной.
 let a = "объект с данными в куче".to_string();
// объект передан переменной b
// переменная a становится неинициализированной
let b = a;
// ошибка!
let c = a;
// данные объекта на стеке                                                                                       
let a = 55;
// копия объекта передана переменной b                                                                   
let b = a;
// c = 55                                                                                        
let c = a;
Заимствования (borrow) с возможностью изменения заимствованного объекта (&mut) и без таковой (&)
Лексически и семантически очень схожи со ссылками, но имеют специфику: заимствование объекта сходно семантике «Либо много читателей, либо один писатель» — объект можно передать в заимствование либо однократно с возможностью изменения объекта, либо многократно без таковой; заимствования можно перезаимствовать другому заемщику. В отличие от обычной семантики «Либо много читателей, либо один писатель», применяется не в контексте синхронизации потоков, а универсально. Контроль корректности заимствований происходит во время компиляции и не порождает дополнительного исполнимого кода (принцип абстракций с нулевой стоимостью). Компилятором контролируется также соотношение времён жизни заимствований и самого объекта — заимствования не могут жить дольше (выходить за пределы области видимости) заимствованного объекта. Заимствования работают с любыми данными независимо от их размещения (стек, локальная или обменная куча, другие специальные расположения). Следует различать независимые понятия — изменяемость собственно заимствования (let mut b = &c) и изменяемость заимствованного объекта (let b = &mut c).
Упаковка (Box)
Простой умный указатель, владеющий объектом в куче. Уничтожает объект и освобождает память при выходе из области видимости.
Ячейка (Cell, RefCell)
Реализует изменяемость содержимого при неизменяемости самой ячейки.
Указатели со счётчиком ссылок (Rc<T>) и с атомарным счётчиком ссылок (Arc<T>)
Умные указатели с подсчётом ссылок, уничтожающие объект и освобождающие память при обнулении счётчика. Arc реализует потокобезопасность для счётчика ссылок (но не для самого объекта). Rc и Arc контролируют неизменяемый объект, поэтому типичное их использование выглядит как Rc<Cell<T>> в однопоточной программе и Arc<Mutex<T>> в многопоточной.
Сырые указатели неизменяемые (*const T) и изменяемые (*mut T)
Указатели без гарантии безопасности. Настоятельно не рекомендуется их использовать.

Связывания неизменяемы по умолчанию, а чтобы объявить переменную изменяемой, необходимо ключевое слово mut.

Примеры:

let x = 80;    // связывание владельца x со значением 80
let mut y = 50;    // изменяемое связывание
let z = &x;    // неизменяемая ссылка на неизменяемое связывание
let w = &mut y;    // неизменяемая ссылка на изменяемое связывание
let r = &mut y;    // ошибка: нельзя создавать вторую ссылку на изменяемое связывание

*w = 90    // y = 90
*z = 30    // ошибка: попытка изменения через ссылку на неизменяемое связывание

let n = Box::new(42);    // упаковка
let m = Rc::new(55);    // счётчик ссылок
let data = Arc::new("test_string")    // атомарный счётчик

Синтаксис[править | править код]

Синтаксис Rust похож на Си и C++; язык регистро-зависимый, блоки кода ограничиваются фигурными скобками; используются стандартные наименования управляющих конструкций if, else, while, и for; комментарии также пишутся в С-формате; имена модулей разделяются двумя символами двоеточия (::). Идентификаторы могут содержать латинские буквы, цифры и знак подчёркивания. В строковых литералах допускается использование любых символов unicode в кодировке UTF-8.

Набор операторов в Rust: арифметические (* — умножение, / — деление, % — взятие остатка от деления, + — сложение, - — вычитание и унарный префиксный оператор - для смены знака числа), битовые (>>, <<, &, | и ^), операторы сравнения (==, !=, <, >, <=, >=), логические (and или && и or или ||). Для приведения типов в Rust используется бинарный оператор as. Неявное приведение типов происходит в очень небольшом наборе ситуаций[29]; отсутствует неявное приведение чисел или строк к булевому значению.

Rust поддерживает макроопределения — средства подстановки с использованием регулярных выражений, выполняющиеся во время этапа подготовки к компиляции, более развитые и безопасные, чем в Си. Макроопределения (макрокоманды) — это определяемые пользователем простые расширения синтаксиса, выполняемые с помощью команды macro_rules! Макрокоманды определяются в том же стиле, что и конструкция сопоставления с образцом. Признак макроса — восклицательный знак в конце имени.

Связывание имён[править | править код]

Ключевое слово let определяет связывание (локальную переменную).

let x: i32 = 5;

Данная запись обозначает: «x — это связывание типа i32 (32-битное целое) со значением пять».

Сопоставление с образцом (match)[править | править код]

В языке Rust конструкция match представляет собой обобщённую и усовершенствованную версию конструкции switch языка C. Более того, match является самым мощным, универсальным и, можно даже сказать, ключевым элементом управления не только потоком выполнения, но и структурами данных в языке.

match x {
    1 | 2 => println!("один или два"),
    3 => println!("три"),
    _ => println!("что угодно"),
}

Деструктуризация. При работе с составным типом данных, вроде struct, можно разобрать его на части («деструктурировать») внутри шаблона:

match origin {
    Point { x, y } => println!("({},{})", x, y),
}

unsafe[править | править код]

В блоках и функциях, помеченных unsafe (англ. unsafe — небезопасный), компилятор разрешает делать лишь четыре дополнительные вещи[30]:

  • читать и обновлять изменяемые статические (static mut) переменные;
  • разыменовывать сырые указатели;
  • вызывать небезопасные (unsafe) функции;
  • реализовывать небезопасные типажи.

К unsafe приходится прибегать для создании низкоуровневых абстракций, в частности — при разработке стандартной библиотеки Rust; обычный код рекомендуется писать без unsafe[31].

Объектная система[править | править код]

В Rust объектная система основана на типажах (traits) и структурах данных. Типажи определяют методы, которые должны быть реализованы для типов. Типаж может содержать реализации методов, принимаемые по умолчанию. Реализация типажей для данной структуры, а также реализация собственных методов структуры обозначается ключевым словом impl. Язык содержит несколько десятков встроенных типажей, большая часть которых используется для перегрузки операторов, а некоторые имеют специальное значение.

Rust поддерживает обобщённые типы (generics). Помимо функций, обобщёнными в Rust могут быть комплексные типы данных, структуры и перечисления. Компилятор Rust компилирует обобщённые функции весьма эффективно, применяя к ним мономорфизацию (генерация отдельной копии каждой обобщённой функции непосредственно в каждой точке её вызова). Таким образом, копия может быть адаптирована под конкретные типы аргументов, а следовательно, и оптимизирована для этих типов. В этом отношении обобщённые функции Rust сравнимы по производительности с шаблонами языка C++.

Параллельные вычисления[править | править код]

В более ранних версиях языка поддерживались легковесные потоки, но потом от них отказались в пользу нативных потоков операционной системы. При этом рекомендуемым методом обмена данными между потоками является отправка сообщений, а не использование общей памяти. Для достижения высокой производительности возможно отправлять данные не через копирование, а используя собственные указатели (Box<T>). Они гарантируют только одного владельца.

Другие особенности[править | править код]

Система модулей
Единица компиляции («крейт») может состоять из нескольких модулей. Иерархия модулей, как правило, совпадает с иерархией каталогов и файлов проекта. Модуль (как правило) является отдельным файлом, а также является пространством имен и одним из средств управления видимостью идентификаторов: в пределах модуля (и в подмодулях) "видны" все идентификаторы, в вышестоящих модулях видны только публичные (pub) функции, типы, типажи, константы, подмодули[32], поля структур[33].
Автоматизированное тестирование
Rust дает возможность реализовать автоматизированные модульные тесты (юнит-тесты) прямо в тестируемом модуле либо подмодуле. Тестовые методы при компиляции игнорируются и вызываются только при тестировании. Интеграционные тесты реализуются как отдельные крейты в подкаталоге src/tests[34].
Автоматизированное документирование
Средство rustdoc позволяет генерировать HTML-документацию прямо из исходного кода. Документация в коде маркируется тройным слешем (/// Пример документации). Поддерживается язык разметки Markdown[35]. В документацию может быть встроен код, который является запускаемым (документационные тесты)[36]. Это позволяет, в том числе, проверять актуальность документации при внесении изменений в проект.
Система управления пакетами
Менеджер пакетов cargo (являющийся также основным инструментом создания, компиляции и тестирования проектов) с помощью файла манифеста Cargo.toml[en] разрешает зависимости проекта (импортируемые крейты), загружая их из репозитория https://crates.io/.
Требования к идентификаторам
Компилятор контролирует выполнение соглашений об именовании переменных, типов, функций и т. д. (snake_case, UpperCamelCase, SCREAMING_SNAKE_CASE), а также неиспользуемые идентификаторы; неиспользуемые идентификаторы рекомендуется начинать со знака подчеркивания; есть определенные рекомендации по именованию конструкторов, методов преобразования типов и др.[37]

Примеры программ[править | править код]

Hello, world![править | править код]

fn main() {
    println!("Hello, world!");
}

Сравнение с другими языками[править | править код]

  • Принципы работы с памятью Rust ощутимо отличаются как от языков с полным доступом к памяти, так и от языков с полным контролем за памятью со стороны сборщика мусора. Модель памяти Rust построена таким образом, что, с одной стороны, предоставляет разработчику возможность контролировать, где размещать данные, вводя разделение по типам указателей и обеспечивая контроль за их использованием на этапе компиляции. C другой стороны, механизм подсчёта ссылок Rust старается выдавать ошибки компиляции в тех случаях, в которых использование прочих языков приводит к ошибкам времени выполнения или аварийному завершению программ.
  • Rust позволяет объявлять функции и блоки кода как «небезопасные» (unsafe). В области такого небезопасного кода не применяются некоторые ограничения, таким образом можно выполнять операции на более низком уровне, но разработчик должен полностью понимать, что он делает.

Применение[править | править код]

  • Среди компаний, активно использующих Rust, можно отметить Mozilla и Dropbox.[38]
  • Ведётся разработка операционной системы, написанной на Rust — Redox.
  • Servo — экспериментальный браузерный движок.

Примечания[править | править код]

  1. 1 2 3 4 https://www.rust-lang.org/en-US/faq.html
  2. 1 2 https://jaxenter.com/mozillas-graydon-hoare-working-on-rust-102672.html
  3. https://blog.rust-lang.org/2018/11/08/Rust-1.30.1.html
  4. Appendix: Influences - The Rust Reference (англ.). Официальный сайт Rust. Проверено 22 октября 2017.
  5. 1 2 https://github.com/rust-lang/rust/blob/master/COPYRIGHT
  6. 1 2 Levy, Amit. The Case for Writing a Kernel in Rust : [англ.] / Amit Levy, Bradford Campbell, Branden Ghena … [et al.] // Proceedings of the 8th Asia-Pacific Workshop on Systems. — N. Y. : ACM, 2017. — P. 1-7. — (APSys '17). — ISBN 978-1-4503-5197-3. — DOI:10.1145/3124680.3124717.
  7. Frequently Asked Questions // Design Patterns (англ.). — Официальный FAQ о языке Rust. — «Many things you can do in OO languages you can do in Rust, but not everything, and not always using the same abstraction you’re accustomed to. […] There are ways of translating object-oriented concepts like multiple inheritance to Rust, but as Rust is not object-oriented the result of the translation may look substantially different from its appearance in an OO language.». Проверено 27 октября 2016.
  8. Ivo Balbaert. Rust Essentials. — Packt Publishing, May 2015. — ISBN 978-1-78528-576-9.
  9. The Rust Core Team. Announcing Rust 1.0 (англ.). The Rust Programming Language Blog (15 May 2015). Проверено 18 августа 2015.
  10. Road to Rust 1.0 - The Rust Programming Language Blog. blog.rust-lang.org. Проверено 11 января 2017.
  11. Frequently Asked Questions // Why is the language called Rust? (англ.). — Историческая версия официального FAQ о языке Rust по состоянию на ноябрь 2015 года; в более поздних версиях текста раздел об истории именования языка исчез. — «As stated by Graydon Hoare, original developer of the Rust language, the name "Rust" comes from his personal interest in fungi, and because it evoked the feeling he was looking for in a programming language name.». Проверено 1 декабря 2016.
  12. Project FAQ (англ.). Официальный сайт Rust (2014). Проверено 17 апреля 2012.
  13. Brendan Eich. Future Tense (англ.) (29 April 2011). — «At Mozilla Summit 2010, we launched Rust, a new programming language motivated by safety and concurrency for parallel hardware, the “manycore” future which is upon us.». Проверено 17 апреля 2012. Архивировано 18 сентября 2012 года.
  14. Graydon Hoare. Rust Progress (англ.) (2 October 2010). Проверено 17 апреля 2012. Архивировано 18 сентября 2012 года.
  15. Graydon Hoare. [rust-dev] stage1/rustc builds (англ.) (20 April 2011). — «After that last change fixing the logging scope context bug, looks like stage1/rustc builds. Just shy of midnight :)». Проверено 17 апреля 2012.
  16. Brian Anderson. The Rust compiler 0.1 is unleashed (англ.). Списки рассылки Mozilla (20 January 2012). Проверено 22 сентября 2014.
  17. Brendan Eich. Mozilla and Samsung Collaborate on Next Generation Web Browser Engine (англ.). Официальный блог Mozilla (3 April 2013). Проверено 22 сентября 2014.
  18. Announcing Rust 1.0.
  19. Stack Overflow Developer Survey 2018 (англ.). Stack Overflow. — «For the third year in a row, Rust is the most loved programming language among our respondents». Проверено 13 марта 2018.
  20. Stack Overflow Developer Survey 2018 (англ.). Stack Overflow. Проверено 13 марта 2018.
  21. The Rust Reference Manual (англ.). Официальный сайт Rust (2014). Проверено 19 сентября 2014.
  22. Generics. doc.rust-lang.org. Проверено 12 января 2017.
  23. Zero Sized Types (ZSTs). doc.rust-lang.org. Проверено 12 января 2017.
  24. Empty Types. doc.rust-lang.org. Проверено 12 января 2017.
  25. std - Rust
  26. The Rust Reference
  27. The Rust Reference
  28. const and static
  29. В частности, поддерживается неявное приведение ссылки к указателю; изменяемой ссылки (указателя) к неизменяемой ссылке (указателю); объекта определённого типа к объекту с типажом, реализованным этим типом. См. Coercions (англ.). — The Rustonomicon. Проверено 25 июля 2017.
  30. Unsafe. doc.rust-lang.org. Проверено 17 октября 2018.
  31. Meet Safe and Unsafe (англ.). The Rustonomicon. Проверено 22 октября 2017.
  32. Modules (англ.). The Rust Programming Language. Проверено 16 октября 2018.
  33. Struct visibility - Rust By Example (англ.). doc.rust-lang.org. Проверено 23 октября 2018.
  34. Testing (англ.). The Rust Programming Language. Проверено 16 октября 2018.
  35. Documentation (англ.). Rust By Example. Проверено 16 октября 2018.
  36. Documentation testing (англ.). Rust By Example. Проверено 16 октября 2018.
  37. Naming (англ.). Rust API Guidelines. Проверено 16 октября 2018.
  38. https://www.rust-lang.org/en-US/friends.html

Литература[править | править код]

Ссылки[править | править код]