- PVSM.RU - https://www.pvsm.ru -
Привет! Представляю вашему вниманию перевод статьи "The Rust Release Team "Announcing Rust 1.34.0" [1].
Команда разработчиков Rust рада сообщить о выпуске новой версии Rust, 1.34.0. Rust — это язык программирования, который даёт возможность каждому создавать надёжное и эффективное программное обеспечение.
Если у вас установлена предыдущая версия Rust с помощью rustup, то для обновления Rust до версии 1.34.0 вам достаточно выполнить:
$ rustup update stable
Если у вас ещё не установлен rustup, вы можете установить его [2] с соответствующей страницы нашего веб-сайта.
Основное улучшение этого выпуска это поддержка альтернативных cargo-реестров. Релиз также включает поддержку ?
в документационных тестах, некоторые улучшения в #[attribute(...)]
и стабилизацию TryFrom
. Читайте далее о ключевых вещах или можете посмотреть подробные примечания к выпуску [3] для дополнительной информации.
cargo
реестрыЕщё до версии 1.0 у Rust был публичный реестр, crates.io [4]. Люди публиковали крейты при помощи cargo publish
и легко подключали эти крейты в секции [dependencies]
в Cargo.toml
.
Однако не все хотят публиковать свои крейты на crates.io. Люди, поддерживающие проекты с закрытым исходным кодом, не могли использовать crates.io, и вместо этого им приходилось указывать git
или path
в зависимостях. Здесь нет ничего такого для небольших проектов, но если в вашей большой организации есть много крейтов с закрытым кодом, вы теряете преимущества поддержки версионирования, которое есть в crates.io.
Начиная с этого выпуска, Cargo может поддерживать альтернативные реестры. Эти реестры сосуществуют с crates.io, так что вы можете писать программы, которые зависят и от crates.io, и от вашего реестра. Однако крейты на crates.io не могут зависеть от внешнего реестра.
Для использования альтернативных реестров, вы должны добавить следующие строки в .cargo/config
. Этот файл может быть в вашей домашней директории (~/.cargo/config
) или быть в директории пакета.
[registries]
my-registry = { index = "https://my-intranet:8080/git/index" }
Добавить зависимость из альтернативного реестра легко. Когда вы указываете зависимость в Cargo.toml
, используйте ключ registry
чтобы Cargo знал что вы хотите получать крейт из альтернативного реестра:
[dependencies]
other-crate = { version = "1.0", registry = "my-registry" }
Как автор крейта, если вы хотите публиковать ваш крейт в альтернативном реестре, первым делом вам надо сохранить аутентификационный токен в ~/.cargo/credentials
при помощи команды cargo login
:
cargo login --registry=my-registry
Далее вы можете использовать флаг --registry
для указания реестра, в который будет публиковаться крейт:
cargo publish --registry=my-registry
О том, как вы можете запустить свой собственный реестр, вы можете найти в документации [5].
?
в документационных тестахВ RFC 1937 [6] было предложено добавить поддержку использования оператора ?
в fn main()
, #[test]
функциях и документационных тестах, позволяя им вернуть Option<T>
или Result<T, E>
где вариант с ошибкой приводит к ненулевому коду завершения в случае fn main()
или упавшему тесту в случае тестов.
Поддержка в fn main()
и #[test]
была реализована достаточно давно [7]. Однако поддержка в документационных тестах была ограничена тестами, в которых явно присутствовал fn main()
.
В этом выпуске добавлена полная поддержка ?
в документационных тестах. Теперь вы можете написать в ваших документационных тестах такое:
/// ```rust
/// use std::io;
/// let mut input = String::new();
/// io::stdin().read_line(&mut input)?;
/// # Ok::<(), io:Error>(())
/// ```
fn my_func() {}
Внизу документационного теста вам всё равно надо указывать тип ошибки, который будет использован.
Процедурные макросы [8] в Rust могут определять пользовательские атрибуты, которые они используют. До текущего момента эти атрибуты были ограничены деревьями путей и литералами в соответствии со следующим синтаксисом:
#[foo(bar)]
#[foo = "bar"]
#[foo = 0]
#[foo(bar = true)]
#[foo(bar, baz(quux, foo = "bar"))]
В отличии от процедурных макросов, эти вспомогательные атрибуты не могли принимать произвольный поток токенов в разделителе, из-за чего вы не могли написать #[range(0..10)]
или #[bound(T: MyTrait)]
. Крейты процедурных макросов вместо этого использовали строки для синтаксиса, подобного такому, например #[range("0..10")]
.
С этим выпуском, пользовательские атрибуты #[attr($tokens)]
позволяют использовать [9] произвольные токены в $tokens
, приводя их в соответствии с макросами. Если вы автор крейта процедурного макроса, пожалуйста проверьте используются ли строки в синтаксисе ваших пользовательских атрибутах и можно ли их заменить на поток токенов.
TryFrom
и TryInto
Трейты TryFrom
[10] и TryInto
[11] были стабилизированы для поддержки ошибок при преобразовании типов.
Например, from_be_bytes
[12] и связанные методы целочисленных типов получают массив, но данные часто читаются через слайсы. Ручное преобразование между слайсами и массивами утомительно. С новыми трейтами это возможно сделать в одну строку с .try_into()
.
let num = u32::from_be_bytes(slice.try_into()?);
Для преобразований, которые не могут завершиться с ошибкой, таких как u8
в u32
, добавлен тип Infallible
[13]. За счёт этого TryFrom
автоматически реализуется для всего, что реализует трейт From
. В будущем, мы надеемся сделать Infallible
псевдонимом для типа !
(never) [14].
fn before_exec
устарела в пользу unsafe fn pre_exec
В Unix-подобных системах функция CommandExt::before_exec
[15] позволяла вам запланировать выполнение замыкания до вызова exec
.
Данное замыкание выполнялось в контексте дочернего процесса после форка. Это означает, что ресурсы, такие как файловые дескрипторы и области памяти, могли быть продублированы. Другими словами, вы могли получить копию значения не Copy
типа в разных процессах, в то время как оригинал оставался бы в родительском. Это могло [16] привести к неопределённому поведению и сломать библиотеки, предполагающие отсутствие дублирования [17].
Следовательно, функция before_exec
должна быть помечена unsafe
. В этом выпуске мы пометили fn before_exec
устаревшей в пользу unsafe fn pre_exec
. При вызове CommandExt::pre_exec
[18] вам необходимо убедиться, что замыкание не нарушает инварианты библиотеки создавая не валидные дубликаты. Если вы предоставляете библиотеку, которая находится в подобной before_exec
ситуации, подумайте об устаревании и предоставьте альтернативу с unsafe
.
В 1.34.0 расширен набор стабильных атомарных целочисленных знаковых и беззнаковых типов, начиная с 8 битных (AtomicU8
[19]) и заканчивая 64 битными.
Ранее [20] были стабилизированы ненулевые беззнаковые целые числа, такие как NonZeroU8
[21]. Благодаря этому Option<NonZeroU8>
имеет такой же размер, как и u8
. В этом выпуске стабилизированы знаковые версии, например NonZeroI8
[22].
Стабилизированы функции iter::from_fn
[23] и iter::successors
[24]. Первая позволяет создать итератор из FnMut() -> Option<T>
. Чтобы итеративно получать элементы из вектора, вы теперь можете написать from_fn(|| vec.pop())
. Тем временем вторая функция создаёт новый итератор, где каждый следующий элемент вычисляется на основе предыдущего.
Дополнительно, были стабилизированы следующие API:
Для подробной информации смотрите подробные примечания к выпуску [3].
Автор: funkill
Источник [36]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/programmirovanie/314772
Ссылки в тексте:
[1] "The Rust Release Team "Announcing Rust 1.34.0": https://blog.rust-lang.org/2019/04/11/Rust-1.34.0.html
[2] установить его: https://www.rust-lang.org/install.html
[3] подробные примечания к выпуску: https://github.com/rust-lang/rust/blob/master/RELEASES.md#version-1340-2019-04-11
[4] crates.io: http://crates.io/
[5] документации: https://doc.rust-lang.org/nightly/cargo/reference/registries.html#running-a-registry
[6] RFC 1937: https://rust-lang.github.io/rfcs/1937-ques-in-main.html
[7] достаточно давно: https://blog.rust-lang.org/2018/05/10/Rust-1.26.html#main-can-return-a-result
[8] Процедурные макросы: https://blog.rust-lang.org/2018/12/21/Procedural-Macros-in-Rust-2018.html
[9] позволяют использовать: https://github.com/rust-lang/rust/pull/57367
[10] TryFrom
: https://doc.rust-lang.org/std/convert/trait.TryFrom.html
[11] TryInto
: https://doc.rust-lang.org/std/convert/trait.TryInto.html
[12] from_be_bytes
: https://doc.rust-lang.org/std/primitive.u32.html#method.from_be_bytes
[13] Infallible
: https://doc.rust-lang.org/std/convert/enum.Infallible.html
[14] типа !
(never): https://github.com/rust-lang/rust/issues/35121
[15] CommandExt::before_exec
: https://doc.rust-lang.org/std/os/unix/process/trait.CommandExt.html#tymethod.before_exec
[16] Это могло: https://github.com/rust-lang/rust/issues/39575#issuecomment-437658766
[17] библиотеки, предполагающие отсутствие дублирования: https://github.com/rust-lang/rust/issues/39575#issuecomment-439645949
[18] CommandExt::pre_exec
: https://doc.rust-lang.org/std/os/unix/process/trait.CommandExt.html#tymethod.pre_exec
[19] AtomicU8
: https://doc.rust-lang.org/std/sync/atomic/struct.AtomicU8.html
[20] Ранее: https://github.com/rust-lang/rust/blob/master/RELEASES.md#version-1280-2018-08-02
[21] NonZeroU8
: https://doc.rust-lang.org/std/num/struct.NonZeroU8.html
[22] NonZeroI8
: https://doc.rust-lang.org/std/num/struct.NonZeroI8.html
[23] iter::from_fn
: https://doc.rust-lang.org/std/iter/fn.from_fn.html
[24] iter::successors
: https://doc.rust-lang.org/std/iter/fn.successors.html
[25] Any::type_id: https://doc.rust-lang.org/std/any/trait.Any.html#tymethod.type_id
[26] Error::type_id: https://doc.rust-lang.org/std/error/trait.Error.html#method.type_id
[27] slice::sort_by_cached_key: https://doc.rust-lang.org/std/primitive.slice.html#method.sort_by_cached_key
[28] str::escape_debug: https://doc.rust-lang.org/std/primitive.str.html#method.escape_debug
[29] str::escape_default: https://doc.rust-lang.org/std/primitive.str.html#method.escape_default
[30] str::escape_unicode: https://doc.rust-lang.org/std/primitive.str.html#method.escape_unicode
[31] str::split_ascii_whitespace: https://doc.rust-lang.org/std/primitive.str.html#method.split_ascii_whitespace
[32] Instant::checked_add: https://doc.rust-lang.org/std/time/struct.Instant.html#method.checked_add
[33] Instant::checked_sub: https://doc.rust-lang.org/std/time/struct.Instant.html#method.checked_sub
[34] SystemTime::checked_add: https://doc.rust-lang.org/std/time/struct.SystemTime.html#method.checked_add
[35] SystemTime::checked_sub: https://doc.rust-lang.org/std/time/struct.SystemTime.html#method.checked_sub
[36] Источник: https://habr.com/ru/post/448366/?utm_campaign=448366
Нажмите здесь для печати.