Команда Rust рада сообщить о новой версии языка — 1.61.0. Rust — это язык программирования, позволяющий каждому создавать надёжное и эффективное программное обеспечение.
Если у вас есть предыдущая версия Rust, установленная через rustup
, то для обновления до версии 1.61.0 вам достаточно выполнить команду:
rustup update stable
Если у вас ещё нет rustup
, то можете установить его со страницы на нашем веб-сайте, а также ознакомиться с подробным описанием выпуска 1.60.0 на GitHub.
Если вы хотите помочь нам протестировать будущие выпуски, вы можете использовать beta (rustup default beta
) или nightly (rustup default nightly
) канал. Пожалуйста, сообщайте обо всех встреченных вами ошибках.
Что стабилизировано в 1.61.0
Пользовательские коды возврата из main
Изначально функция main
могла возвращать только unit-тип ()
(неважно, явно или неявно), всегда обозначая удачное завершение программы. Таким образом, чтобы сообщить о неудаче, вы могли вызвать process::exit(code)
. Начиная с Rust 1.26, main
позволяет возвращать Result
, в котором Ok
транслируется в С-константу EXIT_SUCCESS
, а Err
– в EXIT_FAILURE
(при этом в отладочном виде также выводится сообщение об ошибке). Под капотом эти разные возвращаемые типы были объединены под нестабильным типажом Termination
.
В этом выпуске был стабилизирован типаж Termination
и более общий тип ExitCode
, который абстрагирует платформо-зависимые коды возврата. У него есть константы SUCCESS
и FAILURE
, а также реализация From<u8>
для произвольных значений. Типаж Termination
также может быть реализован для ваших типов, позволяя представлять разные виды сообщений до преобразования их в ExitCode
.
Для примера здесь представлен типобезопасный вариант написания кодов возврата для git bisect run
:
use std::process::{ExitCode, Termination};
#[repr(u8)]
pub enum GitBisectResult {
Good = 0,
Bad = 1,
Skip = 125,
Abort = 255,
}
impl Termination for GitBisectResult {
fn report(self) -> ExitCode {
// Здесь можно вывести сообщение
ExitCode::from(self as u8)
}
}
fn main() -> GitBisectResult {
std::panic::catch_unwind(|| {
todo!("test the commit")
}).unwrap_or(GitBisectResult::Abort)
}
Больше возможностей для const fn
Несколько инкрементальных особенностей было стабилизировано в этом выпуске для предоставления большей функциональности const
функций:
-
Базовая обработка
fn
указателей: теперь вы можете создавать, передавать и преобразовывать указатели на функции вconst fn
. Например, это будет удобно использовать для интерпретаторов при создании таблиц функций во время сборки. Однако пока что не разрешается такие указатели вызывать. -
Ограничения типажей: теперь вы можете написать для
const fn
ограничения типажей в обобщённых параметрах, таких какT: Copy
, где ранее было разрешено толькоSized
. -
dyn Trait
типы: аналогично,const fn
теперь может работать с трейт-объектамиdyn Trait
. -
impl Trait
типы: аргументы и возвращаемое значениеconst fn
теперь могут быть непрозрачнымimpl Trait
типом.
Обратите внимание, что возможности для типажей не позволяют вызывать их методы вconst fn
.
Для получения более подробной информации о текущем состоянии возможностей для const
контекста смотрите раздел Constant Evaluation справочника. Также новые возможности можно отслеживать в rust#57563.
Обработчики блокировки stdio с временем жизни 'static
Каждый из трёх стандартных потоков ввода-вывода Stdin
, Stdout
и Stderr
имеет метод lock(&self)
, позволяющий получить больший контроль над синхронизацией чтения и записи. Однако они возвращают ограничители блокировки со временем жизни, полученным от &self
, из-за чего те ограничены областью видимости исходного метода. Было определено, что это ненужное ограничение, так как нижележащие блокировки находятся в статическом хранилище. Поэтому теперь ограничители возвращаются с временем жизни 'static
, отвязываясь от оригинального метода.
Например, общая ошибка, получаемая при попытке захватить управление и блокировку в одном выражении:
// error[E0716]: temporary value dropped while borrowed
let out = std::io::stdout().lock();
// ^^^^^^^^^^^^^^^^^ - temporary value is freed at the end of this statement
// |
// creates a temporary which is freed while still in use
Теперь ограничитель блокировки стал 'static
и не создаёт временного заимствования, так что этот код будет работать!
Стабилизированные API
Стабилизированы следующие методы и реализации типажей:
Pin::static_mut
Pin::static_ref
Vec::retain_mut
VecDeque::retain_mut
Write
дляCursor<[u8; N]>
std::os::unix::net::SocketAddr::from_pathname
std::process::ExitCode
std::process::Termination
std::thread::JoinHandle::is_finished
Следующие ранее стабилизированные API стали const
:
-
<*const T>::offset
и<*mut T>::offset
-
<*const T>::wrapping_offset
и<*mut T>::wrapping_offset
-
<*const T>::add
и<*mut T>::add
-
<*const T>::sub
и<*mut T>::sub
-
<*const T>::wrapping_add
и<*mut T>::wrapping_add
-
<*const T>::wrapping_sub
и<*mut T>::wrapping_sub
<[T]>::as_mut_ptr
<[T]>::as_ptr_range
<[T]>::as_mut_ptr_range
Прочие изменения
В выпуске Rust 1.61.0 есть и другие изменения: узнайте, что изменилось в Rust, Cargo и Clippy.
В следующем выпуске мы планируем повысить минимальные требования для ядра Linux до версии 3.2 и для glibc до 2.17. Будем рады получить вашу обратную связь в rust#95026.
Участники 1.61.0
Многие люди собрались вместе, чтобы создать Rust 1.61.0. Без вас мы бы не справились. Спасибо!
От переводчиков
С любыми вопросами по языку Rust вам смогут помочь в русскоязычном Телеграм-чате или же в аналогичном чате для новичковых вопросов. Если у вас есть вопросы по переводам или хотите помогать с ними, то обращайтесь в чат переводчиков.
Данную статью совместными усилиями перевели andreevlex, TelegaOvoshey и funkill.
amarao
С интересом узнал про существование
Cursor
,retain_mut
уVec
звучит интересно.