Команда Rust рада представить выпуск Rust 1.21.0. Rust — это системный язык программирования, нацеленный на скорость, безопасность и параллельное выполнение кода.
Если у вас установлена предыдущая версия Rust, для обновления достаточно выполнить:
$ rustup update stable
Если же у вас еще не установлен rustup
, вы можете установить его с соответствующей страницы нашего веб-сайта. С подробными примечаниями к выпуску Rust 1.21.0 можно ознакомиться на GitHub.
Что вошло в стабильную версию 1.21.0
Этот выпуск содержит несколько небольших, но полезных изменений языка и новую документацию.
Первое изменение касается литералов. Рассмотрим код:
let x = &5;
В Rust он аналогичен следующему:
let _x = 5;
let x = &_x;
То есть 5
будет положено в стек или возможно в регистры, а x
будет ссылкой на него.
Однако, учитывая, что речь идет о целочисленном литерале, нет причин делать значение таким локальным. Представьте, что у нас есть функция, принимающая 'static
аргумент вроде std::thread::spawn
. Тогда вы бы могли использовать x
так:
use std::thread;
fn main() {
let x = &5;
thread::spawn(move || {
println!("{}", x);
});
}
Этот код не соберется в прошлых версиях Rust'а:
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;
в нечто вроде:
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
цикла:
// старый способ
for i in 0..10 {
println!("{}", i);
}
// новый способ
(0..10).for_each(|i| println!("{}", i));
Какой из способов лучше зависит от ситуации. В коде выше for
цикл прост, но, если вы выстраиваете цепочку итераторов, версия с for_each
может быть понятнее:
// старый способ
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
может быть использована, когда вы хотите заменить части вашего графа зависимостей. Это можно было сделать и раньше, посредством [relace]
. Если коротко, то [patch]
это новый и более удобный [replace]
. И хотя у нас нет планов убирать или объявлять устаревшим [replace]
, вам скорее всего стоит использовать именно [patch]
.
Как же работает [patch]
? Допустим, у нас есть такой Cargo.toml
:
[dependencies]
foo = "1.2.3"
Так же наш пакет (crate) foo
зависит от пакета bar
, и мы нашли ошибку в bar
. Чтобы проверить это, мы скачиваем исходный код bar
и обновляем наш Cargo.toml
:
[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. Мы не смогли бы этого добиться без участия каждого из вас. Спасибо!
От переводчика: Благодарю vitvakatu за помощь в переводе
Автор: Андрей Лесников