Прежде чем перейти к статье, хочу вам представить, экономическую онлайн игру Brave Knights, в которой вы можете играть и зарабатывать. Регистируйтесь, играйте и зарабатывайте!
Представляем вашему вниманию перевод публикации о новой версии всеми любимого языка программирования Rust.
Введение
Команда разработчиков Rust рада сообщить о выпуске новой версии, 1.37.0. Rust — это язык программирования, позволяющий каждому создавать надёжное и эффективное программное обеспечение.
Если вы установили предыдущую версию Rust средствами rustup, то для обновления до версии 1.37.0 вам достаточно выполнить следующую команду:
$ rustup update stable
Если у вас ещё не установлен rustup
, вы можете установить его с соответствующей страницы нашего веб-сайта, а также посмотреть подробные примечания к выпуску на GitHub.
Что вошло в стабильную версию?
Основные новшества в Rust 1.37.0 включают в себя ссылки на варианты перечисления (enum
) через псевдонимы типов (type
), встроенный cargo vendor
, неименованные константы (const
), profile-guided optimization, ключ default-run
для Cargo проектов и #[repr(align(N))]
для перечислений. Для получения дополнительной информации ознакомьтесь с подробными примечаниями к выпуску.
Ссылки на варианты перечисления (enum
) через псевдонимы типов (type
)
Начиная с Rust 1.37.0, ссылаться на варианты перечисления (enum
) стало возможным через псевдонимы типов:
type ByteOption = Option<u8>;
fn increment_or_zero(x: ByteOption) -> u8 {
match x {
ByteOption::Some(y) => y + 1,
ByteOption::None => 0,
}
}
В impl
блоках Self
выступает в качестве псевдонима типа, поэтому в Rust 1.37.0 стало возможным ссылаться на варианты перечисления, используя синтаксическую конструкцию Self::Variant
:
impl Coin {
fn value_in_cents(&self) -> u8 {
match self {
Self::Penny => 1,
Self::Nickel => 5,
Self::Dime => 10,
Self::Quarter => 25,
}
}
}
А точнее, теперь Rust позволяет ссылаться на варианты перечисления через "type-relative resolution", <MyType<..>>::Variant
. Более подробное описание доступно в отчёте о стабилизации.
Встроенная поддержка Cargo для зависимостей поставщика
После нескольких лет существования в качестве отдельного пакета, команда cargo vendor
теперь интегрирована в Cargo. Данная команда извлекает все зависимости вашего проекта в каталог vendor/
и показывает фрагмент конфигурации, необходимый для использования кода поставщика во время сборки.
cargo vendor
уже применяется в реальных проектах: компилятор Rust rustc
использует его для отправки всех своих зависимостей в tar-архивы выпусков, а проекты с монорепозиториями используют его для фиксации кода зависимостей в системе управления версиями.
Использование неименованных констант (const
) в макросах
Теперь вы можете создавать неименованную (unnamed) константу (const
), подменив её идентификатор подчёркиванием (_
). Например, в компиляторе rustc
мы нашли такой код:
/// Проверка размера типа, где первый параметр
/// это тип, а второй - ожидаемый размер.
#[macro_export]
macro_rules! static_assert_size {
($ty:ty, $size:expr) => {
const _: [(); $size] = [(); ::std::mem::size_of::<$ty>()];
// ^ Обратите внимание на подчеркивание.
}
}
static_assert_size!(Option<Box<String>>, 8); // 1.
static_assert_size!(usize, 8); // 2.
Обратите внимание на второй static_assert_size!(..)
: благодаря использованию неименованных констант стало возможным предотвратить конфликт имён при объявлении новых элементов. Ранее вам нужно было бы написать static_assert_size!(MY_DUMMY_IDENTIFIER, usize, 8);
. С введением неименованных констант становится проще создавать эргономичные и многократно используемые декларативные и процедурные макросы для целей статического анализа.
Profile-guided optimization
В компиляторе rustc
теперь доступна Profile-Guided Optimization (PGO), которую можно включить через флаги компилятора -C profile-generate
и -C profile-use
.
Profile-Guided Optimization — это техника оптимизации программ компиляторами, анализирующая тестовые запуски, вместо исходного кода. Она работает путём компиляции программы для оптимизации в два этапа:
- Сперва программа создаётся средствами инструментария, встроенного в компилятор. Это делается путём передачи
rustc
флага-C profile-generate
. Затем инструментальная программа должна быть запущена на образцах данных и впоследствии она запишет в файл данные профилирования. - Затем программа снова собирается, на этот раз подавая собранные данные профилирования обратно в
rustc
с помощью флага-C profile-use
. Эта сборка будет использовать собранные данные, чтобы позволить компилятору принимать лучшие решения о размещении кода, встраивании и других оптимизациях.
Для получения более подробной информации о Profile-Guided Optimization смотрите соответствующую главу в книге по компилятору rustc.
Выбор исполняемого файла в Cargo проектах
cargo run
является весьма удобным инструментом для быстрого тестирования консольных приложений. Когда в одном пакете присутствует несколько исполняемых файлов, необходимо явно объявить имя того исполняемого файла, который вы хотите запустить при помощи флага --bin
. Это делает cargo run
не таким эргономичным, как хотелось бы, особенно когда определённый исполняемый файл вызывается чаще, чем другие.
Rust 1.37.0 решает данную проблему путём добавления нового ключа default-run
в Cargo.toml
(секция [package]
). Таким образом, при необнаружении флага --bin
, Cargo запустит двоичный файл, объявленный в конфигурации.
#[repr(align(N))]
для перечислений
Начиная с Rust 1.37.0, атрибут #[repr(align(N))]
может быть использован для определения выравнивания перечислений в памяти (ранее данный атрибут был разрешён только для структур (struct
) и объединений (union
)). Например, перечисление Align16
будет, как и ожидалось, иметь выравнивание в 16
байт, тогда как естественное выравнивание без #[repr(align(16))]
будет 4
:
#[repr(align(16))]
enum Align16 {
Foo { foo: u32 },
Bar { bar: u32 },
}
Семантика использования #[repr(align(N))
для перечислений такая же, как определение обёртки для структуры AlignN<T>
с этим выравниванием, а затем использование AlignN<MyEnum>
:
#[repr(align(N))]
struct AlignN<T>(T);
Изменения в стандартной библиотеке
Rust 1.37.0 стабилизировал следующие компоненты стандартной библиотеки:
BufReader::buffer
иBufWriter::buffer
Cell::from_mut
Cell::as_slice_of_cells
DoubleEndedIterator::nth_back
Option::xor
{i,u}{8,16,64,128,size}::reverse_bits
иWrapping::reverse_bits
slice::copy_within
Другие изменения
Синтаксис, пакетный менеджер Cargo и анализатор Clippy также претерпели некоторые изменения.
Участники 1.37.0
Множество людей собрались вместе, чтобы создать Rust 1.37.0. Мы не смогли бы сделать это без всех вас, спасибо!
Новые спонсоры инфраструктуры Rust
Мы хотели бы поблагодарить двух новых спонсоров инфраструктуры Rust, предоставивших ресурсы, необходимых для создания Rust 1.37.0: Amazon Web Services (AWS) и Microsoft Azure:
- AWS предоставили хостинг для артефактов выпуска (компиляторы, библиотеки, инструменты и исходный код), дали доступ до этих артефактов пользователям через CloudFront, предотвратили регрессии на EC2 с Crater и управляли другой инфраструктурой, связанной с Rust, размещённой на AWS.
- Для чрезвычайно ресурсоёмкого тестирования репозитория rust-lang/rust Microsoft Azure предоставила сборщики.
От переводчиков
С любыми вопросами по языку Rust вам смогут помочь в русскоязычном Телеграм-чате или же в аналогичном чате для новичковых вопросов.
Данную статью совместными усилиями перевели andreevlex, ozkriff, funkill и Gymmasssorla.