Команда 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_mutPin::static_refVec::retain_mutVecDeque::retain_mutWriteдляCursor<[u8; N]>std::os::unix::net::SocketAddr::from_pathnamestd::process::ExitCodestd::process::Terminationstd::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.