Cайт веб-разработчика, программиста Ruby on Rails ESV Corp. Екатеринбург, Москва, Санкт-Петербург, Новосибирск, Первоуральск

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

Rust programming language (official site)

Rust programming language (by Steve Klabnik, Carol Nichols, and Chris Krycho, with contributions from the Rust Community)

Rust reference , keywords

Crate std

crates.io

Rust edition guide

 

Rust по-русски

Язык программирования Rust: описание (от Стива Клабника и Кэрол Николс, при поддержке других участников сообщества Rust)

Изучить Rust (официальный сайт)

Rustonomicon (рус.)

Asynchronous Programming in Rust (рус.)

Язык программирования Rust - русское сообщество

 

Ruby + Rust

Magnus

High level Ruby bindings. Write Ruby extension gems in Rust, or call Ruby code from a Rust binary.

Magnus

crate Magnus, API doc, Getting started

doc crate serde_magnus

Поддержка вызова кода Rust из Ruby поддерживается на уровне языка, инструмент bundler:
bundle gem --ext=rust

 


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

Ключевые приоритеты языка: безопасность, скорость и параллелизм. 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 по 2024 год Rust занимает первое место в списке самых любимых языков программированияMost loved programming languages» / «Most admired programming languages») по версии ежегодного опроса разработчиков Stack Overflow Developer Survey.

История

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

В 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.

Оосбенности Rust

Управление памятью

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

Реализована так называемая Move-семантика: по умолчанию Rust «переносит» (move) указатель на объект в куче новому владельцу при присваивании, делая старую переменную недействительной. Этого не происходит, если тип реализует типаж Copy, поскольку данные в стеке копируются.

Ещё одна особенность модели памяти — поддержка заимствований (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.

Параллельные вычисления

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

Определение и вызов асинхронных операций поддерживаются на уровне синтаксиса языка: ключевое слово async определяет асинхронную функцию или блок; обычный вызов такой функции возвращает объект с типажом Future — дескриптор ленивой асинхронной операции. Вызов .await позволяет одной асинхронной операции ждать, пока не завершится другая асинхронная операция. При этом реализация среды исполнения асинхронных операций не входит ни в ядро языка, ни в стандартную библиотеку, а предоставляется сторонними библиотеками.

Объектная система

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

Rust поддерживает аналогию наследования типажей — типаж может требовать от реализующего типа реализацию других типажей. Однако языковой поддержки наследования самих типов, и следовательно, классического ООП, в Rust нет. Вместо наследования типов, аналогия иерархии классов реализуется введением типажей, включением структуры-предка в структуру-потомка или введением перечислений для обобщения разных структур.

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

Другие особенности

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

Автоматизированное тестирование: язык даёт возможность реализовать автоматизированные модульные тесты (юнит-тесты) прямо в тестируемом модуле либо подмодуле. Тестовые методы при компиляции игнорируются и вызываются только при тестировании. Интеграционные тесты реализуются как отдельные крейты в каталоге tests.

Автоматизированное документирование: средство rustdoc позволяет генерировать HTML-документацию прямо из исходного кода. Документация в коде маркируется тройным слешем (/// Пример документации) либо двойным с восклицательным знаком, для документации модулей — (//! Пример документации модуля). Поддерживается язык разметки Markdown. В документацию может быть встроен код, который является запускаемым (документационные тесты). Это позволяет, в том числе, проверять актуальность документации при внесении изменений в проект.

Система управления пакетами: менеджер пакетов cargo (являющийся также основным инструментом создания, компиляции и тестирования проектов) с помощью файла манифеста Cargo.toml разрешает зависимости проекта (импортируемые крейты), загружая их из репозитория crates.io.

Требования к идентификаторам: компилятор контролирует выполнение соглашений об именовании переменных, типов, функций и так далее (snake_case, UpperCamelCase, SCREAMING_SNAKE_CASE), а также неиспользуемые идентификаторы; неиспользуемые идентификаторы рекомендуется начинать со знака подчёркивания; есть определённые рекомендации по именованию конструкторов, методов преобразования типов и др.