Rust (Раст, ; ) — мультипарадигменный компилируемый язык программирования общего назначения, сочетающий парадигмы функционального и процедурного программирования с объектной системой, основанной на типажах. Управление памятью осуществляется через механизм «владения» с использованием , что позволяет обходиться без системы сборки мусора во время исполнения программы. Rust гарантирует безопасную работу с памятью благодаря встроенной в компилятор системе статической проверки ссылок (). Имеются средства, позволяющие использовать приёмы объектно-ориентированного программирования.

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

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

Разрабатывается с 2010-х годов сообществом Mozilla Research и финансировался фондом Mozilla Foundation. С 2020 года планировалась передача интеллектуальной собственности и процессов развития и финансирования языка в организацию Rust Foundation. 8 февраля 2021 года пять компаний-учредителей (AWS, Huawei, Google, Microsoft и Mozilla) официально объявили о создании Rust Foundation.

Десять лет подряд с 2016 по 2025 год Rust занимает первое место в списке самых любимых языков программирования («Most loved programming languages» / «Most admired programming languages») по версии ежегодного опроса разработчиков Stack Overflow Developer Survey.

История Работа над языком была начата сотрудником Mozilla Грэйдоном Хором в 2006 году. Автор дал проекту название Rust, по его словам, связанное с грибами семейства ржавчинные ().

В 2009 году компания Mozilla начала отдельно спонсировать разработку Rust. Спустя год язык был официально представлен на Mozilla Summit 2010. Изначальный компилятор, реализованный на OCaml, был заменён на новый, написанный на Rust и использовавший LLVM для генерации машинного кода; в следующем году новый компилятор впервые успешно скомпилировал сам себя.

Первая официальная альфа-версия Rust (0.1) была выпущена в январе 2012 года.

В апреле 2013 года был запущен Servo — экспериментальный проект компании Mozilla по разработке браузерного движка на Rust.

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

В декабре 2022 года Rust стал первым языком, кроме C и ассемблера, который поддерживается при разработке ядра Linux.

Система типов Используется сильная статическая типизация. Поддерживается обобщённое программирование с поддержкой параметрического полиморфизма, обеспечивается автоматический вывод типов для локальных переменных (но не для параметров функций).

Реализована поддержка данных — типов, которые имеют ровно один экземпляр и не занимают места в памяти, примеры: пустой кортеж (); пустой массив (например, [u8; 0]); структура без полей (напр. struct Foo); структура с единичными типами (struct Foo([u8; 0], ())).

Реализованы пустые типы данных — типы, экземпляры которых не могут быть созданы; реализованы в виде перечисляемых типов, не имеющих вариантов: enum Void {}.

Все типы данных в языке делятся на две основные группы: простые и типы стандартной библиотеки.

Простые типы (типы постоянной длины, встроенные в сам язык) — числовой, булев, символьный, массив, срез, строковый срез, кортеж, ссылка, указатель на функцию. Часть простых типов является «машинной», то есть реализуются непосредственно в современных процессорах — таковы числовой, булев и символьный. Типы, предоставляемые стандартной библиотекой 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 Число с плавающей запятой (float). f32, f64. Примеры: 3.14f32, 6.0221e23f64, 2.,

Булев (bool): true, false.

Символьный (char): тип, представляющий символ Unicode (внутреннее представление данных как u32). Примеры значений: '₽', '\n', '\x7f', '\u{CA0}',

Указатель на функцию (function pointer): объекты-функции имеют тип, определяемый их сигнатурой, то есть параметрами и возвращаемым значением. Пример: let f: fn(i32) -> i32 = plus_one;

Ссылка (разделяемое заимствование — shared borrow) &T (разделяемая, не изменяемая, не владеющая ресурсом), вместо того, чтобы забирать владение ресурсом, она его заимствует. Имена, которые заимствуют что-то, не освобождают ресурс, когда они выходят из области видимости. Кроме того, имена-владельцы переходят в заимствованное состояние.

Ссылка изменяемая (изменяемое заимствование — mutable borrow) &mut T (не владеющая ресурсом). Позволяет изменять ресурс, который заимствуется.

Структуры (struct): структура си-подобная: struct Color {red: u8, green: u8, blue: u8} структура-кортеж: struct Color (u8, u8, u8); структура — «единичное» значение: struct Electron;

Коллекции: Массив (array) [T; N] — последовательность фиксированного размера N из однотипных (типа T) элементов. Примеры: [1, 2, 3], [true; 10000]. Вектор (vec, vector) 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".

Перечисление (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. Похожи на постоянные, но статические значения не встраиваются в место их использования. Это значит, что каждое значение существует в единственном экземпляре, и у него есть определённый адрес. Также может быть изменяемым, при помощи ключевого слова mut. Изменения возможны только в unsafe блоках.

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

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

Реализована так называемая Move-семантика: по умолчанию Rust «переносит» (move) указатель на объект в куче новому владельцу при присваивании, делая старую переменную недействительной. Этого не происходит, если тип реализует типаж Copy, поскольку данные в стеке копируются. let a = "объект с данными в куче".to_string(); // объект передан переменной b // переменная a становится неинициализированной let b = a; // ошибка! let c = a;// данные объекта на стеке let a = 55; // копия объекта передана переменной b let b = a; // c = 55 let c = a;