Rust (англ. rust — ржавчина, произносится [rʌst] — раст) — мультипарадигмальный компилируемый язык программирования общего назначения, спонсируемый Mozilla Research, сочетающий парадигмы функционального и процедурного программирования с объектной системой, основанной на типажах, и с управлением памятью через понятие «владения» (систему аффинных типов[en][7], позволяющую обходиться без сборки мусора). Объектно-ориентированное программирование как таковое языком не поддерживается, но язык позволяет реализовать большинство понятий ООП при помощи других абстракций[8].
Ключевые особенности языка: безопасность, скорость и параллелизм. Rust пригоден для системного программирования, в частности, он рассматривается как перспективный язык для разработки ядер операционных систем[7]. Rust сопоставим по скорости и возможностям с C++, однако даёт большую безопасность при работе с памятью, что обеспечивается механизмами ограничения. Rust также направлен на достижение «абстракции с нулевой стоимостью»[9].
После нескольких лет активной разработки первая стабильная версия (1.0) вышла 15 мая 2015 года, после чего новые версии выходят раз в 6 недель[10]. Для версий языка, вышедших после 1.0, заявлена обратная совместимость[11].
Язык отчасти берёт своё название от грибов семейства ржавчинные (англ. rust fungi)[12].
enum Void {}
.В Rust все типы можно разделить на две основные группы:
std
(переменной длины): Вектор, Строка, Хеш-таблица и т. д.-5i8
, 0x400_u16
, 0o100i16
, 20_922_789_888u64
, b'*'
(байтовый литерал), b'\x1b'
, 42
(тип этого значения будет выведен автоматически), 0xfff_fc00usize
,3.14f32
, 6.0221e23f64
, 2.
,true
, false
.'₽'
, '\n'
, '\x7f'
, '\u{CA0}'
,let f: fn(i32) -> i32 = plus_one;
&T
(разделяемая, не изменяемая, не владеющая ресурсом), вместо того, чтобы забирать владение ресурсом, она его заимствует. Имена, которые заимствуют что-то, не освобождают ресурс, когда они выходят из области видимости. Кроме того, имена-владельцы переходят в заимствованное состояние[28].&mut T
(не владеющая ресурсом). Позволяет изменять ресурс, который заимствуется.[1, 2, 3]
, [true; 10000]
.vec![0; 10];
, Vec::with_capacity(10)
&a[1..4]
,("Age", 22)
, ("Europe",)
,HashMap::new();
Vec<u8>
) — тип, владеющий содержимым. String представляет собой строку, размещённую в куче. Эта строка расширяема, и она гарантированно является корректной последовательностью байтов с точки зрения UTF-8. String обычно создаётся путём преобразования из строкового среза с использованием метода to_string. Примеры: "строковый срез".to_string()
, String::new()
."строковый срез"
. &'static str - строка, введённая символами в коде самой программы, - тот же строковый срез, только статически размещённый (сохраняемый в скомпилированной программе).
r"\d{0,5}.*"
.b"white"
.struct Color {red: u8, green: u8, blue: u8}
struct Color (u8, u8, u8);
struct Electron;
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
позволяет делать оптимизации вроде Свёртки констант[29].
В Rust реализована «умная» модель памяти, поддерживающая эффективные структуры данных и безопасные шаблоны параллельного выполнения, а также полностью запрещающая некорректный доступ к памяти, который обычно является источником критических ошибок сегментации в других языках программирования. Отсутствие нулевых указателей; контроль за использованием неинициализированных и деинициализированных переменных; невозможность совместного использования разделяемых состояний несколькими задачами; статический анализ времени жизни указателей; проверка на выход за пределы массива (автоматически и всегда).
Модель памяти Rust можно охарактеризовать следующими терминами.
let a = "объект с данными в куче".to_string();
// объект передан переменной b
// переменная a становится неинициализированной
let b = a;
// ошибка!
let c = a;
// данные объекта на стеке
let a = 55;
// копия объекта передана переменной b
let b = a;
// c = 55
let c = a;
&mut
) и без таковой (&
)let mut b = &c
) и изменяемость заимствованного объекта (let b = &mut c
).Rc<T>
) и с атомарным счётчиком ссылок (Arc<T>
)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
. Неявное приведение типов происходит в очень небольшом наборе ситуаций[30]; отсутствует неявное приведение чисел или строк к булевому значению.
Rust поддерживает макроопределения — средства подстановки с использованием регулярных выражений, выполняющиеся во время этапа подготовки к компиляции, более развитые и безопасные, чем в Си. Макроопределения (макрокоманды) — это определяемые пользователем простые расширения синтаксиса, выполняемые с помощью команды macro_rules!
Макрокоманды определяются в том же стиле, что и конструкция сопоставления с образцом. Признак макроса — восклицательный знак в конце имени.
Ключевое слово let
определяет связывание (локальную переменную).
let x: i32 = 5;
Данная запись обозначает: «x
— это связывание типа i32
(32-битное целое) со значением пять».
В языке Rust конструкция match представляет собой обобщённую и усовершенствованную версию конструкции switch языка C. Более того, match является самым мощным, универсальным и, можно даже сказать, ключевым элементом управления не только потоком выполнения, но и структурами данных в языке.
match x {
1 | 2 => println!("один или два"),
3 => println!("три"),
_ => println!("что угодно"),
}
Деструктуризация. При работе с составным типом данных, вроде struct, можно разобрать его на части («деструктурировать») внутри шаблона:
match origin {
Point { x, y } => println!("({},{})", x, y),
}
В блоках и функциях, помеченных unsafe
(англ. unsafe — небезопасный), компилятор разрешает делать лишь четыре дополнительные вещи[31]:
static mut
) переменные;unsafe
) функции;К unsafe
приходится прибегать для создании низкоуровневых абстракций, в частности — при разработке стандартной библиотеки Rust; обычный код рекомендуется писать без unsafe
[32].
В Rust объектная система основана на типажах (traits) и структурах данных. Типажи определяют методы, которые должны быть реализованы для типов. Типаж может содержать реализации методов, принимаемые по умолчанию. Реализация типажей для данной структуры, а также реализация собственных методов структуры обозначается ключевым словом impl
. Язык содержит несколько десятков встроенных типажей, большая часть которых используется для перегрузки операторов, а некоторые имеют специальное значение.
Rust поддерживает обобщённые типы (generics). Помимо функций, обобщёнными в Rust могут быть комплексные типы данных, структуры и перечисления. Компилятор Rust компилирует обобщённые функции весьма эффективно, применяя к ним мономорфизацию (генерация отдельной копии каждой обобщённой функции непосредственно в каждой точке её вызова). Таким образом, копия может быть адаптирована под конкретные типы аргументов, а следовательно, и оптимизирована для этих типов. В этом отношении обобщённые функции Rust сравнимы по производительности с шаблонами языка C++.
В более ранних версиях языка поддерживались легковесные потоки, но потом от них отказались в пользу нативных потоков операционной системы. При этом рекомендуемым методом обмена данными между потоками является отправка сообщений, а не использование общей памяти. Для достижения высокой производительности возможно отправлять данные не через копирование, а используя собственные указатели (Box<T>
). Они гарантируют только одного владельца.
pub
) функции, типы, типажи, константы, подмодули[33], поля структур[34].tests
[35]./// Пример документации
). Поддерживается язык разметки Markdown[36]. В документацию может быть встроен код, который является запускаемым (документационные тесты)[37]. Это позволяет, в том числе, проверять актуальность документации при внесении изменений в проект.fn main() {
println!("Hello, world!");
}
unsafe
). В области такого небезопасного кода не применяются некоторые ограничения, таким образом можно выполнять операции на более низком уровне, но разработчик должен полностью понимать, что он делает.Среди компаний, активно использующих Rust, можно отметить Mozilla и Dropbox.[39] В качестве примеров разработок на Rust можно привести:
Данная страница на сайте WikiSort.ru содержит текст со страницы сайта "Википедия".
Если Вы хотите её отредактировать, то можете сделать это на странице редактирования в Википедии.
Если сделанные Вами правки не будут кем-нибудь удалены, то через несколько дней они появятся на сайте WikiSort.ru .