Выпуск Rust 1.21
Команда Rust рада представить выпуск Rust 1.21.0. Rust — это системный язык программирования, нацеленный на скорость, безопасность и параллельное выполнение кода.
Если у вас установлена предыдущая версия Rust, для обновления достаточно выполнить:
1 | $ rustup update stable
|
Если же у вас ещё не установлен rustup
, вы можете установить его
с соответствующей страницы нашего веб-сайта.
С подробными примечаниями к выпуску Rust 1.21.0 можно ознакомиться на GitHub.
Что вошло в стабильную версию 1.21.0
Этот выпуск содержит несколько небольших, но полезных изменений языка и новую документацию.
Первое изменение касается литералов. Рассмотрим код:
1 | let x = &5; |
В Rust он аналогичен следующему:
1 2 | let _x = 5; let x = &_x; |
То есть 5
будет положено в стек или возможно в регистры,
а x
будет ссылкой на него.
Однако, учитывая, что речь идёт о целочисленном литерале,
нет причин делать значение таким локальным.
Представьте, что у нас есть функция, принимающая 'static
аргумент
вроде std::thread::spawn
.
Тогда вы бы могли использовать x
так:
1 2 3 4 5 6 7 8 9 | use std::thread; fn main() { let x = &5; thread::spawn(move || { println!("{}", x); }); } |
Этот код не соберётся в прошлых версиях Rust’а:
1 2 3 4 5 6 7 8 9 10 | error[E0597]: borrowed value does not live long enough --> src/main.rs:4:14 | 4 | let x = &5; | ^ does not live long enough ... 10 | } | - temporary value only lives until here | = note: borrowed value must be valid for the static lifetime... |
Из-за локальности 5
, ссылка на него тоже живёт слишком мало,
чтобы удовлетворить требованиям spawn
.
Но если вы соберёте это с Rust 1.21, оно заработает. Почему?
Если что-то, на что создана ссылка, можно положить в static
,
мы могли бы «обессахарить» let x = &5;
в нечто вроде:
1 2 3 | static FIVE: i32 = 5; let x = &FIVE; |
И раз FIVE
является static
, то x
является &'static i32
.
Так Rust теперь и будет работать в подобных случаях.
Подробности смотрите в RFC 1414,
который был принят в январе 2017, но начинался ещё в декабре 2015!
Теперь мы запускаем LLVM параллельно с кодогенерацией, что должно снизить пиковое потребление памяти.
RLS теперь может быть установлен
через rustup вызовом
rustup component add rls-preview
.
Много полезных инструментов, таких как RLS,
Clippy и rustfmt
, все ещё требуют ночной Rust,
но это первый шаг к их работе на стабильном канале.
Ожидайте дальнейших улучшений в будущем,
а пока взгляните на предварительную версию
Теперь об улучшениях документации. Первое: если вы посмотрите на
документацию модуля std::os
,
содержащего функционал работы с операционными системами,
вы увидите не только Linux
— платформу, на которой документация была собрана.
Нас долго расстраивало, что официальная документация была только для Linux.
Это первый шаг к исправлению ситуации,
хотя пока что это доступно только
для стандартной библиотеки,
а не для любого пакета (crate).
Мы надеемся исправить это в будущем.
Далее, документация Cargo переезжает! Исторически документация Cargo была размещена на doc.crates.io, что не следовало модели выпусков (release train model), хотя сам Cargo следовал. Это приводило к ситуациям, когда какой-то функционал скоро должен был «влиться» в ночной Cargo, документация обновлялась, и в течение следующих 12 недель пользователи думали, что все работает, хотя это ещё не было правдой. https://doc.rust-lang.org/cargo будет новым домом для документации Cargo, хотя сейчас этот адрес просто перенаправляет на doc.crates.io. Будущие выпуски переместят настоящую документацию Cargo, и тогда уже doc.crates.io будет перенаправлять на doc.rust-lang.org/cargo. Документация Cargo уже давно нуждается в обновлении, так что ожидайте ещё новостей о ней в скором будущем!
Наконец, до этого выпуска у rustdoc
не было документации.
Теперь это исправлено:
добавлена новая книга «rustdoc
Book»,
доступная по адресу https://doc.rust-lang.org/rustdoc.
Сейчас эта документация очень примитивна, но со временем она улучшится.
Подробности смотрите в примечаниях к выпуску.
Стабилизации в стандартной библиотеке
В этом выпуске не так много стабилизаций, но есть кое-что,
очень упрощающее жизнь:
из-за отсутствия обобщения относительно целых чисел (type-level integers),
массивы поддерживали типажи только до размера 32.
Теперь это исправлено для типажа Clone
.
Кстати, это же вызывало много ICE (внутренних ошибок компилятора),
когда тип реализовывал только Copy
, но не Clone
.
Для других типажей недавно
был принят RFC об обобщении относительно целых чисел,
который должен исправить ситуацию.
Это изменение ещё не реализовано, но подготовительные работы уже ведутся.
Затем был стабилизирован Iterator::for_each
,
дующий возможность поглощать итератор ради побочных эффектов
без for
цикла:
1 2 3 4 5 6 7 | // старый способ for i in 0..10 { println!("{}", i); } // новый способ (0..10).for_each(|i| println!("{}", i)); |
Какой из способов лучше зависит от ситуации.
В коде выше for
цикл прост,
но, если вы выстраиваете цепочку итераторов,
версия с for_each
может быть понятнее:
1 2 3 4 5 6 7 8 9 10 | // старый способ for i in (0..100).map(|x| x + 1).filter(|x| x % 2 == 0) { println!("{}", i); } // новый способ (0..100) .map(|x| x + 1) .filter(|x| x % 2 == 0) .for_each(|i| println!("{}", i)); |
Стабилизированы функции max
и min
типажа Ord
.
Стабилизирована встроенная функция (intrinsic) needs_drop
.
Наконец, был стабилизирован std::mem::discriminant
,
позволяющий вам узнать активный вариант перечисления
без использования match
оператора.
Подробности смотрите в примечаниях к выпуску.
Функционал Cargo
Помимо вышеупомянутых изменений документации
Cargo в этом выпуске получает большое обновление:
[patch]
.
Разработанная в RFC 1969,
секция [patch]
вашего Cargo.toml
может быть использована, когда вы хотите
заменить части вашего графа зависимостей.
Это можно было сделать и раньше, посредством [replace]
.
Если коротко, то [patch]
это новый и более удобный [replace]
.
И хотя у нас нет планов убирать или объявлять устаревшим [replace]
,
вам скорее всего стоит использовать именно [patch]
.
Как же работает [patch]
? Допустим, у нас есть такой Cargo.toml
:
1 2 | [dependencies] foo = "1.2.3" |
Так же наш пакет (crate) foo
зависит от пакета bar
,
и мы нашли ошибку в bar
.
Чтобы проверить это, мы скачиваем исходный код bar
и обновляем наш Cargo.toml
:
1 2 3 4 5 | [dependencies] foo = "1.2.3" [patch.crates-io] bar = { path = '/path/to/bar' } |
Теперь при выполнении cargo build
будет использована наша локальная версия bar
,
а не версия из crates.io
, от которой на самом деле зависит foo
.
Подробности смотрите в документации.
Также:
- Теперь вы можете использовать
cargo install
для одновременной установки сразу нескольких пакетов. - Аргумент
--all
автоматически добавляется к команде, если вы в виртуальном рабочем пространстве (virtual workspace). - Поля
include
иexclude
в вашемCargo.toml
теперь принимают шаблоны аналогичные.gitignore
.
Подробности смотрите в примечаниях к выпуску.
Разработчики 1.21.0
Множество людей участвовало в разработке Rust 1.19. Мы не смогли бы этого добиться без участия каждого из вас. Спасибо!