- PVSM.RU - https://www.pvsm.ru -

Выпуск Rust 1.21

Команда Rust рада представить выпуск Rust 1.21.0. Rust — это системный язык программирования, нацеленный на скорость, безопасность и параллельное выполнение кода.

Если у вас установлена предыдущая версия Rust, для обновления достаточно выполнить:

$ rustup update stable

Если же у вас еще не установлен rustup, вы можете установить его [1] с соответствующей страницы нашего веб-сайта. С подробными примечаниями к выпуску Rust 1.21.0 [2] можно ознакомиться на 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 [3], который был принят в январе 2017, но начинался еще в декабре 2015!

Теперь мы запускаем LLVM параллельно с кодогенерацией [4], что должно снизить пиковое потребление памяти.

RLS [5] теперь может быть установлен через rustup [6] вызовом rustup component add rls-preview. Много полезных инструментов, таких как RLS, Clippy и rustfmt, все еще требуют ночной Rust, но это первый шаг к их работе на стабильном канале. Ожидайте дальнейших улучшений в будущем, а пока взгляните на предварительную версию

Теперь об улучшениях документации. Первое: если вы посмотрите на документацию модуля std::os [7], содержащего функционал работы с операционными системами, вы увидите не только Linux — платформу, на которой документация была собрана. Нас долго расстраивало, что официальная документация была только для Linux. Это первый шаг к исправлению ситуации,
хотя пока что это доступно только для стандартной библиотеки [8],
а не для любого пакета (crate). Мы надеемся исправить это в будущем.

Далее, документация Cargo переезжает! [9] Исторически документация Cargo была размещена на doc.crates.io, что не следовало модели выпусков (release train model), хотя сам Cargo следовал. Это приводило к ситуациям, когда какой-то функционал скоро должен
был "влиться" в ночной Cargo, документация обновлялась, и в течение следующих 12 недель пользователи думали, что все работает, хотя это еще не было правдой. https://doc.rust-lang.org/cargo [10] будет новым домом для документации Cargo, хотя сейчас этот адрес просто перенаправляет на doc.crates.io. Будущие выпуски переместят настоящую документацию Cargo, и тогда уже doc.crates.io будет перенаправлять на doc.rust-lang.org/cargo. Документация Cargo уже давно нуждается в обновлении, так что ожидайте еще новостей о ней в скором будущем!

Наконец, до этого выпуска у rustdoc не было документации. Теперь это исправлено [11]: добавлена новая книга "rustdoc Book", доступная по адресу https://doc.rust-lang.org/rustdoc [12]. Сейчас эта документация очень примитивна, но со временем она улучшится.

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

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

В этом выпуске не так много стабилизаций, но есть кое-что, очень упрощающее жизнь: из-за отсутствия обобщения относительно целых чисел (type-level integers), массивы поддерживали типажи только до размера 32. Теперь это исправлено для типажа Clone [13]. Кстати, это же вызывало много ICE (внутренних ошибок компилятора), когда тип реализовывал только Copy, но не Clone.
Для других типажей недавно был принят RFC об обобщении относительно целых чисел [14], который должен исправить ситуацию. Это изменение еще не реализовано, но подготовительные работы уже ведутся.

Затем был стабилизирован Iterator::for_each [15], дающий возможность поглощать итератор ради побочных эффектов без 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));

Rc<T> и Arc<T> теперь реализуют From<&[T]> where T: Clone, From<str>, From<String>, From<Box<T>> where T: ?Sized, и From<Vec<T>>. [16]

Стабилизированы функции max и min типажа Ord [17].

Стабилизирована встроенная функция (intrinsic) needs_drop [18].

Наконец, был стабилизирован std::mem::discriminant [19], позволяющий вам узнать активный вариант перечисления без использования match оператора.

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

Функционал Cargo

Помимо вышеупомянутых изменений документации Cargo в этом выпуске получает большое обновление: [patch] [20]. Разработанная в RFC 1969 [21], секция [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.

Подробности смотрите в
документации [22].

Также:

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

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

Множество людей участвовало в разработке Rust 1.19. Мы не смогли бы этого добиться без участия каждого из вас. Спасибо! [26]

От переводчика: Благодарю vitvakatu [27] за помощь в переводе

Автор: Андрей Лесников

Источник [28]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/programmirovanie/265759

Ссылки в тексте:

[1] установить его: https://www.rust-lang.org/install.html

[2] подробными примечаниями к выпуску Rust 1.21.0: https://github.com/rust-lang/rust/blob/master/RELEASES.md#version-1210-2017-10-12

[3] RFC 1414: https://github.com/rust-lang/rfcs/blob/master/text/1414-rvalue_static_promotion.md

[4] запускаем LLVM параллельно с кодогенерацией: https://github.com/rust-lang/rust/pull/43506

[5] RLS: https://github.com/rust-lang-nursery/rls/

[6] через rustup: https://github.com/rust-lang/rust/pull/44204

[7] документацию модуля std::os: https://doc.rust-lang.org/stable/std/os/

[8] для стандартной библиотеки: https://github.com/rust-lang/rust/pull/43348

[9] документация Cargo переезжает!: https://github.com/rust-lang/rust/pull/43916

[10] https://doc.rust-lang.org/cargo: https://doc.rust-lang.org/cargo

[11] исправлено: https://github.com/rust-lang/rust/pull/43863

[12] https://doc.rust-lang.org/rustdoc: https://doc.rust-lang.org/rustdoc

[13] это исправлено для типажа Clone: https://github.com/rust-lang/rust/pull/43690

[14] был принят RFC об обобщении относительно целых чисел: https://github.com/rust-lang/rfcs/blob/master/text/2000-const-generics.md

[15] Iterator::for_each: https://github.com/rust-lang/rust/pull/44567

[16] Rc<T> и Arc<T> теперь реализуют From<&[T]> where T: Clone, From<str>, From<String>, From<Box<T>> where T: ?Sized, и From<Vec<T>>.: https://github.com/rust-lang/rust/pull/42565

[17] функции max и min типажа Ord: https://github.com/rust-lang/rust/pull/44593

[18] встроенная функция (intrinsic) needs_drop: https://github.com/rust-lang/rust/pull/44639

[19] был стабилизирован std::mem::discriminant: https://doc.rust-lang.org/std/mem/fn.discriminant.html

[20] [patch]: https://github.com/rust-lang/cargo/pull/4123

[21] RFC 1969: https://github.com/rust-lang/rfcs/blob/master/text/1969-cargo-prepublish.md

[22] документации: http://doc.crates.io/manifest.html#the-patch-section

[23] Теперь вы можете использовать cargo install для одновременной установки сразу нескольких пакетов: https://github.com/rust-lang/cargo/pull/4216

[24] Аргумент --all автоматически добавляется к команде, если вы в виртуальном рабочем пространстве (virtual workspace): https://github.com/rust-lang/cargo/pull/4335

[25] Поля include и exclude в вашем Cargo.toml теперь принимают шаблоны аналогичные .gitignore: https://github.com/rust-lang/cargo/pull/4270

[26] Спасибо!: https://thanks.rust-lang.org/rust/1.21.0

[27] vitvakatu: https://habrahabr.ru/users/vitvakatu/

[28] Источник: https://habrahabr.ru/post/340170/?utm_source=habrahabr&utm_medium=rss&utm_campaign=best