Хабрахабр

[Перевод] Выпуск Rust 1.31 и Rust 2018

31. Команда разработчиков Rust рада сообщить о выпуске новой версии Rust, 1. Rust — это язык программирования, который дает возможность каждому создавать надежное и эффективное программное обеспечение. 0, а также "Rust 2018".

31. Если у вас установлена предыдущая версия Rust с помощью rustup, то для обновления Rust до версии 1. 0 вам достаточно выполнить:

$ rustup update stable

С подробными примечаниями к выпуску Rust 1. Если у вас еще не установлен rustup, вы можете установить его с соответствующей страницы нашего веб-сайта. 0 можно ознакомиться на GitHub. 31.

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

31, возможно, самый значительный выпуск со времен Rust 1. Rust 1. В данный выпуск включена первая итерация «Rust 2018», но это не единственное нововведение! 0! Обзор улучшений будет длинный, поэтому вот оглавление:

  • Rust 2018
    • Нелексические времена жизни
    • Изменения системы модулей
  • Дополнительные правила вывода времен жизни
  • const fn
  • Новые инструменты
  • Инструментальные проверки качества кода
  • Документация
  • Предметные рабочие группы
  • Новый веб-сайт
  • Стабилизация стандартной библиотеки
  • Улучшения в Cargo
  • Разработчики выпуска

Rust 2018

За подробностями зачем нужен Rust 2018, обратитесь к этим публикациям. Мы писали о Rust 2018 впервые в марте, и затем в июле. Также об этом можно почитать в посте на Mozilla Hacks (перевод). В данном обзоре нам и так много что нужно рассказать, поэтому мы сосредоточимся только на том, что такое Rust 2018.

Rust 2018 — это нечто большее, чем просто набор улучшений языка. Вкратце, Rust 2018 — это возможность объединить в связное целое всю работу, которую мы проделали за последние три года. В дополнении к ним, он включает:

  • Инструментарий (поддержка в IDE, rustfmt, Clippy)
  • Документацию
  • Работу предметных рабочих групп
  • Новый веб-сайт

Дальше мы расскажем обо всем этом подробнее и о других нововведениях.

Давайте создадим новый проект с помощью Cargo:

$ cargo new foo

Вот содержимое Cargo.toml:

[package]
name = "foo"
version = "0.1.0"
authors = ["Your Name <you@example.com>"]
edition = "2018" [dependencies]

Обратите внимание, что он установлен в 2018. В секцию [package] был добавлен новый ключ: edition. Вы также можете установить его в 2015 — это значение будет установлено по умолчанию, если ключ отсутствует.

С использованием Rust 2018 будут разблокированы некоторые новые возможности, которые не разрешены в Rust 2015.

Ваш проект 2018 редакции может использовать зависимости 2015 редакции, а проект 2015 редакции может использовать зависимости 2018 редакции. Важно отметить, что каждый пакет может быть в режиме 2015 или 2018, и они будут работать вместе. Кроме того, когда вы решите перенести код Rust 2015 на Rust 2018, изменения могут быть внесены автоматически через cargo fix. Это гарантирует целостность экосистемы и что все новые возможности будут опциональны, сохраняя совместимость с существующим кодом.

Во-первых, они добавляются также и в Rust 2015, если оказываются совместимы с особенностями этой редакции. Вы можете спросить: а что с самими новыми возможностями? Вы можете посмотреть руководство по редакциям, чтобы узнать минимальную версию rustc для каждой новой возможности и другие ее требования. Таким образом, большая часть языка остается одинаковой везде. Однако, есть несколько больших нововведений, о которых нужно упомянуть отдельно: нелексические времена жизни и некоторые изменения в системе модулей.

Нелексические времена жизни

Это — жаргонизм, который, если говорить простыми словами, означает: анализатор заимствований стал умнее и теперь принимает некоторый корректный код, который до этого отклонял. Если вы следили за развитием Rust последние несколько лет, то вы могли время от времени встречать термин "NLL" или "нелексические времена жизни" ("non-lexical lifetimes"). Рассмотрим пример:

fn main() { let mut x = 5; let y = &x; let z = &mut x;
}

Раньше Rust выдавал ошибку компиляции:

error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immutable --> src/main.rs:5:18 |
4 | let y = &x; | - immutable borrow occurs here
5 | 6 | let z = &mut x; | ^ mutable borrow occurs here
7 | } | - immutable borrow ends here

С кодом выше все в порядке, но анализатор зависимостей не мог этого понять. Это потому, что область жизни ссылок определялась "лексически"; то есть, заимствование y считалось активным, пока y не выйдет из области видимости в конце main, даже если мы никогда больше не используем y внутри области.

Теперь этот код замечательно компилируется.

Например так: Но что, если бы мы использовали y?

fn main() ", y);
}

Раньше Rust выдавал вам такую ошибку:

error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immutable --> src/main.rs:5:18 |
4 | let y = &x; | - immutable borrow occurs here
5 | let z = &mut x; | ^ mutable borrow occurs here
...
8 | } | - immutable borrow ends here

В Rust 2018 это сообщение об ошибке улучшилось:

error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immutable --> src/main.rs:5:13 |
4 | let y = &x; | -- immutable borrow occurs here
5 | let z = &mut x; | ^^^^^^ mutable borrow occurs here
6 | 7 | println!("y: {}", y); | - borrow later used here

Это значительно упрощает отладку ошибок такого рода. Вместо того, чтобы указывать, где y выходит из области видимости, оно показывает, где происходит конфликтное заимствование.

31 это улучшение исключительно для Rust 2018. В Rust 1. Мы планируем добавить его в Rust 2015 позже.

Изменения системы модулей

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

Поэтому редакция 2018 вносит некоторые изменения в то, как работают пути, упрощая систему модулей и делая ее понятнее.

Вот краткое резюме:

  • extern crate больше не требуется практически нигде.
  • Вы можете импортировать макросы с помощью use, вместо использования атрибута #[macro_use].
  • Абсолютные пути начинаются с имени контейнера, где ключевое слово crate относится к текущему контейнеру.
  • foo.rs и поддиректория foo/ могут сосуществовать; mod.rs больше не требуется при размещении подмодулей в поддиректории.

Это выглядит как произвольный набор правил, но в целом ментальная модель теперь значительно упростилась.

Тут еще много деталей, пожалуйста, обратитесь к руководству по редакциям за выяснением всех подробностей.

Дополнительные правила вывода времен жизни

Код вроде такого: Давайте поговорим об улучшении, доступном в обоих редакциях: мы добавили некоторые дополнительные правила вывода для блоков impl и определений функций.

impl<'a> Reader for BufReader<'a> { // здесь методы
}

может быть теперь записан так:

impl Reader for BufReader<'_> { // здесь методы
}

Время жизни '_ по-прежнему показывает, чтоBufReader принимает его как параметр, но нам больше не нужно задавать для него имя.

Однако нам больше не нужно писать столько шаблонного кода, как раньше: Времена жизни все еще требуется определять в структурах.

// Rust 2015
struct Ref<'a, T: 'a> { field: &'a T
} // Rust 2018
struct Ref<'a, T> { field: &'a T
}

Вы все еще можете указать ее явно, если хотите. Зависимость : 'a будет выведена. Мы рассматриваем и другие возможности для вывода в подобных местах на будущее, но пока не имеем конкретных планов.

const fn

В этом выпуске добавлен новый способ объявления функции: const fn. В Rust есть несколько способов объявления функции: fn для обычных функций, unsafe fn для небезопасных функций и extern fn для внешних функций. Он используется так:

const fn foo(x: i32) -> i32 { x + 1
}

При этом она выполнится во время компиляции, а не во время выполнения программы. Константная функция может вызываться как обычная функция, но помимо этого она может использоваться в любом константном контексте. Например:

const SIX: i32 = foo(5);

Функция foo выполнится во время компиляции и SIX примет значение 6.

Это важно из соображений надежности. Константные функции не могут делать все то, что могут делать нормальные функции: они должны иметь детерминированный результат. Вот некоторые примеры того, что вы можете в них делать: В текущем виде константные функции могут совершать минимальное подмножество операций.

  • Использовать целочисленные арифметические операции и операции сравнения
  • Использовать любые логические операции, кроме && и ||
  • Конструировать массивы, структуры, перечисления и кортежи
  • Вызывать другие константные функции
  • Обращаться по индексу в массивах и срезах
  • Обращаться к полям структур и кортежей
  • Использовать константы (но не статические значения, и даже не ссылки на них)
  • Использовать & и * ссылки
  • Приводить типы, исключая приведение сырого указателя к целочисленному значению

Мы будем расширять возможности константных функций, но приведенного выше набора уже достаточно, чтобы использовать const fn на практике.

Подробности смотрите в справочнике.

Новые инструменты

Cargo, Rustdoc и Rustup были основными инструментами, начиная с версии 1. Редакция 2018 знаменует начало нового уровня зрелости экосистемы инструментов Rust. 0; с редакцией 2018 приходит новое поколение инструментов, которыми теперь все могут пользоваться: Clippy, Rustfmt и поддержка IDE.

Вы можете установить его через rustup component add clippy и запустить командой cargo clippy. Статический анализатор кода clippy теперь доступен в стабильном Rust. 0 и имеет такие же гарантии стабильности статических проверок, что и rustc. Clippy теперь получил версию 1. Это означает, что код, который компилируется с clippy, будет продолжать компилироваться с clippy (при условии, что для проверок не задано генерировать
ошибку через deny), но может выдавать новые предупреждения. Новые проверки могут добавляться, или может расширяться функционал старых, но старые не могут быть удалены (могут быть только помечены как устаревшие).

Автоматическое форматирование кода позволит вам сэкономить время, кроме того, оно приблизит ваш код к официальному стилю Rust. Rustfmt — это инструмент для форматирования кода в Rust. Вы можете установить его через rustup component add rustfmt и использовать командой cargo fmt.

0. Текущий выпуск включает Rustfmt 1. Обратная совместимость означает, что теперь практично запускать Rustfmt на вашем CI (используйте cargo fmt --check). Отныне мы гарантируем обратную совместимость для Rustfmt: если вы отформатируете свой код сегодня, то форматирование не изменится в будущем (только для параметров по умолчанию). Попробуйте это вместе с "форматированием при сохранении" в редакторе, и ваш рабочий процесс революционизируется.

Сейчас имеется несколько решений высокого качества: Поддержка IDE — одна из самых востребованных возможностей инструментов для Rust.

В частности, автодополнение кода в редакторах, основанных на RLS, не на высоте. Работа по поддержке в IDE не закончена. Однако, если вы в основном хотите поддержку типов, документации и "перехода к определению", то вы останетесь довольны.

Инструментальные проверки качества кода (tool lints)

30 мы стабилизировали "инструментальные атрибуты", такие как #[rustfmt::skip]. В Rust 1. 31 мы стабилизировали нечто подобное: "инструментальные проверки качества кода" ("tool lints"), такие как #[allow(clippy::bool_comparison)]. В Rust 1. Это позволяет задавать пространства имен для проверок, чтобы стало понятнее, из каких инструментов они берутся.

Если вы ранее использовали проверки Clippy, вы можете выполнить миграцию следующим образом:

// было
#![cfg_attr(feature = "cargo-clippy", allow(bool_comparison))] // стало
#![allow(clippy::bool_comparison)]

Вам также теперь будут выдаваться предупреждения, которые помогут перейти на использование нового стиля. Вам больше не нужен cfg_attr!

Документация

Вы можете купить бумажную копию от No Starch Press! В Rustdoc было несколько улучшений в этом году, и была выпущена полностью переписанная книга "The Rust Programming Language".

Ведь и печатное издание планируется периодически обновлять. Раньше ее называли "вторым изданием" книги, но, так как она стала первым печатным изданием, то это вызвало путаницу. Книга довольно хорошо продается и собирает деньги для Black Girls Code. В конце концов, после множества дискуссий с No Starch, было решено обновлять книгу на веб-сайте вместе с каждым выпуском, а No Starch будет периодически забирать изменения и печатать их.

Вы можете найти новую версию книги здесь.

Предметные рабочие группы

В этом году мы объявили о создании четырех рабочих групп:

  • Сетевые сервисы
  • Приложения командной строки
  • WebAssembly
  • Встроенные устройства

Вот некоторые достижения: Группы очень усердно работали, чтобы сделать Rust лучше в каждой из этих областей.

  • В сетевых сервисах переработали интерфейс для Futures, а сверх этого еще и async/await. Эти улучшения еще не выпущены, но мы уже близки к этому!
  • Команда CLI работала над библиотеками и документацией, чтобы сделать приложения командной строки лучше.
  • Группа WebAssembly выпустила множество инструментов мирового уровня для использования Rust с wasm.
  • Для встроенных устройств появилась возможность вести разработку ARM на стабильном Rust!

Обо всем этом подробнее можно узнать на нашем новом сайте!

Новый веб-сайт

Теперь она стала официальной версией rust-lang.org! На прошлой неделе мы анонсировали новую версию нашего веб-сайта.

И хотя до полного завершения еще многое нужно сделать, мы гордимся проделанной работой. Для ее создания потребовался год работы многих людей.

Стабилизация стандартной библиотеки

Были добавлены новые реализации From:

  • u8 теперь реализует From<NonZeroU8>, аналогично и для других числовых типов и их NonZero эквивалентов
  • Option<&T> реализует From<&Option<T>>, аналогично и для &mut

Также были стабилизированы следующие функции:

Подробности смотрите в примечаниях к выпуску.

Улучшения в Cargo

Cargo теперь будет загружать пакеты параллельно, используя HTTP/2.

Поэтому вы можете делать это в Cargo.toml таким образом: Кроме того, так как extern crate указывать теперь не обязательно, было бы неприятно писать extern crate foo as bar; для переименования зависимости.

[dependencies]
baz = { version = "0.1", package = "foo" }

или, что эквивалентно:

[dependencies.baz]
version = "0.1"
package = "foo"

Теперь пакет foo доступен как baz для использования в вашем коде.

Подробности смотрите в примечаниях к выпуску.

Разработчики 1.31.0

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

От переводчика: выражаю отдельную благодарность участникам сообщества Rustycrate и лично @dashadee, ozkriff, humbug и mvlabat за помощь с переводом и вычиткой.

Теги
Показать больше

Похожие статьи

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»
Закрыть