Выпуск Rust 1.36.0: Трейт Future, стабилизация alloc и MaybeUninit<T>
Представляю вашему вниманию перевод публикации о новой версии всеми любимого языка программирования Rust.
Команда по разработке языка программирования Rust рада анонсировать новую версию, 1.36.0. Rust — это язык программирования, позволяющий каждому разрабатывать надёжное и быстрое ПО.
Если предыдущую версию Rust вы установили средствами rustup
, получение текущей версии не составит особого труда:
$ rustup update stable
Если у Вас всё ещё нет rustup
, Вы можете получить его с соответствующей страницы на нашем сайте. Детальный обзор данного релиза доступен на GitHub.
Данный релиз привнёс множество изменений, включая стабилизацию долгожданного трейта Future
, крейта alloc
, структуры MaybeUninit
, NNL для Rust 2015
, новую реализацию HashMap
и поддержку флага --offline
в Cargo.
Ниже описаны наиболее значительные изменения, однако вы также можете посмотреть детальный список нововведений для дополнительной осведомлённости.
Rust 1.36.0 стабилизировал долгожданный трейт Future
!
Мы надеемся, что это нововведение позволит популярным крейтам, библиотекам, и, в целом, всей экосистеме подготовиться к синтаксису async
/.await
, стабилизация которого планируется на недалёкое будущее.
До версии 1.36.0, стандартная библиотека состояла из крейтов std
, core
и proc_macro
. Крейт core
имел базовую функциональность (такую как Iterator
и Copy
) и мог быть использован в средах с #![no_std]
, так как он не налагал никаких требований. Между тем, крейт std
поставлял такие типы, как Box
, а также функциональность операционной системы (глобальный аллокатор).
Начиная с Rust 1.36.0, части крейта std
, зависимые от глобального аллокатора, например, Vec, сейчас доступны в крейте alloc
. Крейт std
, тем временем, реэкспортирует данные части.
В то время как программы с #![no_std]
, использующие крейт alloc
, всё ещё требуют канала nightly
, библиотеки с #![no_std]
могут использовать крейт alloc
в стабильном Rust.
Также отметим, что все «обычные» программы (без #![no_std]
) в своих зависимостях способны содержать описанные выше библиотеки с #![no_std]
. Мы надеемся, что это будет содействовать разработке экосистемы, совместимой с #![no_std]
.
Если вы являетесь разработчиком библиотеки, требующей примитивы аллокации для функционирования, советуем пометить свою библиотеку как совместимой с #![no_std]
, используя следующий синтаксис в начале файла lib.rs
:
#![no_std]
extern crate alloc;
use alloc::vec::Vec;
В предыдущих релизах Rust, функция mem::uninitialized
разрешала вам отменять проверки инициализации, так как полагала, что вы УЖЕ выполнили инициализацию типа T
, не делая ничего. Одно из использований данной функции была «ленивая» аллокация массивов.
Однако mem::uninitalized
является чрезмерно опасной операцией, которая не может быть правильно использована с компилятором Rust, предполагающим, что все значения проинициализированы должным образом.
Например, вызов mem::uninitialized::
немедленно вызовет неопределённое поведение, так как с точки зрения Rust, неинициализированные биты являются либо нулём (false
), либо единицей (true
), и лишь два вышеописанных паттерна подходят для типа bool
.
Чтобы разрешить данную ситуацию, в Rust 1.36.0 был стабилизирован тип MaybeUninit
. Компилятор Rust теперь не предполагает, что MaybeUninit
является инициализированным типом T
. Тем самым, вы можете выполнять постепенную инициализацию более безопасно и наконец-то использовать .assume_init()
когда вы уверены, что maybe_t: MaybeUninit
содержит инициализированный тип T
.
Так как MaybeUninit
является более безопасной альтернативой, начиная с Rust 1.38, функция mem::uninitialized
будет помечена устаревшей.
Чтобы узнать больше о неинициализированной памяти, mem::uninitialized
и MaybeUninit
, почитайте статью Алексиса Бессесснера. Стандартная библиотека также содержит достаточную документацию о MaybeUninit
.
В объявлении о Rust 1.31.0 мы рассказали вам о NLL (нелексические лайфтаймы), нововведении в язык, делающим проверятеля ссылок (borrow checker) умнее и дружелюбнее. Например, теперь вы можете написать так:
fn main() {
let mut x = 5;
let y = &x;
let z = &mut x; // Не было разрешено до 1.31.0
}
В 1.31.0, NLL был стабилизирован только для Rust 2018, и предполагалось, что мы перенесём его в Rust 2015 в будущем. Это было сделано в Rust 1.36.0, NLL стал доступным для Rust 2015.
С NLL, поддерживаемым в обеих версиях, мы приближаемся к удалению старого проверятеля ссылок. Однако старый проверятель ссылок, к сожалению, принял беззвучный код, который он НЕ должен был принять.
И, как результат, NLL сейчас находится на стадии «миграции», в которой мы будем выдавать предупреждения вместо ошибок в том случае, если проверятель ссылок NLL не одобрит код, который бы одобрил старый проверятель ссылок на основе AST. Советуем взглянуть на список пострадавших публичных крейтов.
Чтобы узнать больше о NLL, MIR, истории о правке «беззвучных дыр», и о том, что вы можете сделать с предупреждениями компилятора, прочтите статью Феликса Клока.
В Rust 1.36.0, предыдущая реализация HashMap
была заменена реализацией из крейта hashbrown
, основанной на дизайне SwissTable. Интерфейс остался прежним, но нынешняя реализация в среднем быстрее и потребляет меньше памяти. Однако заметьте, что стандартная реализация всё ещё использует алгоритм SipHash 1–3.
Во время большинства сборок, Cargo не использует вашу сеть. Однако, в некоторых моментах, например, когда новая зависимость была добавлена, Cargo всё-же вынужден потребить сетевые ресурсы. Иногда такое поведение недопустимо (в изолированной системе или в самолёте).
В Rust 1.36.0, новый флаг --offline
был стабилизирован. Данный флаг отменяет алгоритм разрешения зависимостей, вместо этого используя локальные закешированные зависимости.
Если запрашиваемые крейты недоступны без сети, которая была отключена, то Cargo завершит работу с ошибкой. Чтобы предварительно заполнить локальный кеш до ухода из сети, используйте команду cargo fetch
, загружающую все необходимые зависимости для конкретного проекта.
Чтобы узнать больше о --offline
и cargo fetch
, прочтите статью Ника Камерона. Другие изменения в Cargo детально описаны тут.
Макрос
dbg!
стал поддерживать множественные аргументы;Некоторые методы были помечены словом
const
:Стабилизированы некоторые API, включая:
Подробные описания изменений в версии 1.36.0 доступны для Rust, стандартной библиотеки, Cargo и Clippy.
Множество людей собрались вместе, чтобы создать Rust 1.36.0. Мы не смогли бы сделать это без всех вас, спасибо!
С любыми вопросами по языку Rust вам смогут помочь в русскоязычном Телеграм-чате или же в аналогичном чате для новичковых вопросов.