Выпуск Rust 1.36.0: Трейт Future, стабилизация alloc и MaybeUninit<T>

в 16:40, , рубрики: cargo, clippy, open source, release, Rust, rustc, rustdoc, rustfix, rustfmt, stable, выпуск версий, новости технологий, перевод, системное программирование, стабильная версия, языки программирования

Представляю вашему вниманию перевод публикации о новой версии всеми любимого языка программирования Rust.

Введение

Команда по разработке языка программирования Rust рада анонсировать новую версию, 1.36.0. Rust — это язык программирования, позволяющий каждому разрабатывать надёжное и быстрое ПО.

Если предыдущую версию Rust вы установили средствами rustup, получение текущей версии не составит особого труда:

$ rustup update stable

Если у Вас всё ещё нет rustup, Вы можете получить его с соответствующей страницы на нашем сайте. Детальный обзор данного релиза доступен на GitHub.

Что вошло в стабильную версию?

Данный релиз привнёс множество изменений, включая стабилизацию долгожданного трейта Future, крейта alloc, структуры MaybeUninit<T>, NNL для Rust 2015, новую реализацию HashMap<K, V> и поддержку флага --offline в Cargo.

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

Стабилизация трейта Future

Rust 1.36.0 стабилизировал долгожданный трейт Future!

Мы надеемся, что это нововведение позволит популярным крейтам, библиотекам, и, в целом, всей экосистеме подготовиться к синтаксису async/.await, стабилизация которого планируется на недалёкое будущее.

Стабилизация крейта alloc

До версии 1.36.0, стандартная библиотека состояла из крейтов std, core и proc_macro. Крейт core имел базовую функциональность (такую как Iterator и Copy) и мог быть использован в средах с #![no_std], так как он не налагал никаких требований. Между тем, крейт std поставлял такие типы, как Box<T>, а также функциональность операционной системы (глобальный аллокатор).

Начиная с 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;

MaybeUninit место mem::uninitialized

В предыдущих релизах Rust, функция mem::uninitialized разрешала вам отменять проверки инициализации, так как полагала, что вы УЖЕ выполнили инициализацию типа T, не делая ничего. Одно из использований данной функции была "ленивая" аллокация массивов.

Однако mem::uninitalized является чрезмерно опасной операцией, которая не может быть правильно использована с компилятором Rust, предполагающим, что все значения проинициализированы должным образом.

Например, вызов mem::uninitialized::<bool>() немедленно вызовет неопределённое поведение, так как с точки зрения Rust, неинициализированные биты являются либо нулём (false), либо единицей (true), и лишь два вышеописанных паттерна подходят для типа bool.

Чтобы разрешить данную ситуацию, в Rust 1.36.0 был стабилизирован тип MaybeUninit<T>. Компилятор Rust теперь не предполагает, что MaybeUninit<T> является инициализированным типом T. Тем самым, вы можете выполнять постепенную инициализацию более безопасно и наконец-то использовать .assume_init() когда вы уверены, что maybe_t: MaybeUninit<T> содержит инициализированный тип T.

Так как MaybeUninit<T> является более безопасной альтернативой, начиная с Rust 1.38, функция mem::uninitialized будет помечена устаревшей.

Чтобы узнать больше о неинициализированной памяти, mem::uninitialized и MaybeUninit<T>, почитайте статью Алексиса Бессесснера. Стандартная библиотека также содержит достаточную документацию о MaybeUninit<T>.

NLL для Rust 2015

В объявлении о 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, истории о правке "беззвучных дыр", и о том, что вы можете сделать с предупреждениями компилятора, прочтите статью Феликса Клока.

Новая реализация HashMap

В Rust 1.36.0, предыдущая реализация HashMap<K, V> была заменена реализацией из крейта hashbrown, основанной на дизайне SwissTable. Интерфейс остался прежним, но нынешняя реализация в среднем быстрее и потребляет меньше памяти. Однако заметьте, что стандартная реализация всё ещё использует алгоритм SipHash 1-3.

Поддержка --offline в Cargo

Во время большинства сборок, Cargo не использует вашу сеть. Однако, в некоторых моментах, например, когда новая зависимость была добавлена, Cargo всё-же вынужден потребить сетевые ресурсы. Иногда такое поведение недопустимо (в изолированной системе или в самолёте).

В Rust 1.36.0, новый флаг --offline был стабилизирован. Данный флаг отменяет алгоритм разрешения зависимостей, вместо этого используя локальные закешированные зависимости.

Если запрашиваемые крейты недоступны без сети, которая была отключена, то Cargo завершит работу с ошибкой. Чтобы предварительно заполнить локальный кеш до ухода из сети, используйте команду cargo fetch, загружающую все необходимые зависимости для конкретного проекта.

Чтобы узнать больше о --offline и cargo fetch, прочтите статью Ника Камерона. Другие изменения в Cargo детально описаны тут.

Изменения в библиотеке

Другие изменения

Подробные описания изменений в версии 1.36.0 доступны для Rust, стандартной библиотеки, Cargo и Clippy.

Участники 1.36.0

Множество людей собрались вместе, чтобы создать Rust 1.36.0. Мы не смогли бы сделать это без всех вас, спасибо!

От переводчика

С любыми вопросами по языку Rust вам смогут помочь в русскоязычном Телеграм-чате или же в аналогичном чате для новичковых вопросов.

Автор: Gymmasssorla

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js