[Перевод] Rust 1.63.0: потоки области видимости, I/O безопасность, NLL во всех редакциях по умолчанию

b2c4e4922fb3e9e08a877a7c427bf791

Команда Rust рада сообщить о новой версии языка — 1.63.0. Rust — это язык программирования, позволяющий каждому создавать надёжное и эффективное программное обеспечение.

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

rustup update stable

Если у вас ещё нет rustup, то можете установить его со страницы на нашем веб-сайте, а также ознакомиться с подробным описанием выпуска 1.63.0 на GitHub.

Если вы хотите помочь нам протестировать будущие выпуски, вы можете использовать beta (rustup default beta) или nightly (rustup default nightly) канал. Пожалуйста, сообщайте обо всех встреченных вами ошибках.


Что стабилизировано в 1.63.0

В стандартную библиотеку добавлены потоки, которые гарантировано завершаются в конце области видимости. Завершена миграция всех редакций языка на NLL. Добавлены новые типы для работы с дискриптерами файлов операционной системы.


Потоки области видимости

Код Rust мог запускать новые потоки с помощью std::thread::spawn начиная с версии 1.0, но эта функция ограничена временем жизни 'static в замыкании. Грубо говоря, это означает, что потоки в настоящее время должны владеть любыми аргументами, переданными в их замыкание; вы не можете передавать заимствованные данные в поток. В тех случаях, когда ожидается, что потоки завершатся к концу функции (путём вызоваjoin()), это не является строго необходимым и может потребовать обходных путей, таких как размещение данных в Arc.

Начиная, с 1.63.0, стандартная библиотека добавляет потоки с ограниченной областью действия, которые позволяют порождать поток, заимствующий из локального фрейма стека. API std::thread::scope обеспечивает необходимую гарантию того, что любые порождённые потоки завершатся до своего возвращения, что позволяет безопасно заимствовать данные. Вот пример:

let mut a = vec![1, 2, 3];
let mut x = 0;

std::thread::scope(|s| {
    s.spawn(|| {
        println!("hello from the first scoped thread");
        // Вы можете заимствовать `a` здесь.
        dbg!(&a);
    });
    s.spawn(|| {
        println!("hello from the second scoped thread");
        //  Вы так же можете изменить заимствованную переменную `x` здесь
        // потому что нет других потоков которые ёё используют.
        x += a[0] + a[2];
    });
    println!("hello from the main thread");
});

// После переменные снова вам доступны и вы можете их изменять:
a.push(4);
assert_eq!(x, a.len());


Владение для сырых файловых дескрипторов (I/O безопасность)

Раньше код Rust, работающий с API-интерфейсами платформы, принимающими необработанные файловые дескрипторы (на платформах в стиле Unix) или дескрипторы (в Windows), обычно работал напрямую с представлением дескриптора, специфичным для платформы (например, c_int или псевдонимом RawFd). Для привязок Rust к таким нативным API система типов не смогла закодировать, станет ли API владельцем дескриптора файла (например, close) или просто заимствует его (например, dup).

Теперь Rust предоставляет типы-оболочки, такие как BorrowedFd и OwnedFd, которые помечены как #[repr(transparent)], что означает, что внешние привязки extern "C" могут напрямую использовать эти типы для кодирования семантики владения. Полный список типов оболочек, стабилизированных в версии 1.63, см. в разделе «Стабилизированные API». В настоящее время они доступны на платформах cfg (unix), Windows и WASI.

Мы рекомендуем, чтобы новые API использовали эти типы вместо псевдонимов предыдущих типов (например RawFd).


`::<> для обобщений в функциях с impl Trait

Нотация ::<> может быть использована для уточнения типа параметра (fn foo) даже когда типом аргумента указан impl Trait. Но указание типа для аргумента impl Trait через эту нотацию по-прежнему невозможно.


Завершение миграции нелексических времён жизни

Как описывалось в этом посте, мы полностью удалили предыдущий лексический анализатор заимствований из rustc для всех редакций, а новый нелексический анализатор заимствований стал работать в полную силу. Теперь анализатор заимствований не воздействует на вывод rustc. Это не меняет поведения программ, но завершает длительную миграцию, начавшуюся со стабилизации NLL в 2018 редакции, которая привносит все преимущества нового анализатора заимствований во все редакции Rust. Для большинства пользователей это изменение будет выглядеть как слегка улучшенная диагностика некоторых ошибок заимствований, но это не повлияет на то, какой код они могут писать.

Узнать больше про нелексические времена жизни вы можете в этом разделе анонса 2018 редакции.


Стабилизированные API

Стабилизированы следующие методы и реализации трейтов:

Следующие API теперь возможно использовать в const контексте:


Прочие изменения

Синтаксис, пакетный менеджер Cargo и анализатор Clippy также претерпели некоторые изменения.


Участники 1.63.0

Многие люди собрались вместе, чтобы создать Rust 1.63.0. Без вас мы бы не справились. Спасибо!


От переводчиков

С любыми вопросами по языку Rust вам смогут помочь в русскоязычном Телеграм-чате или же в аналогичном чате для новичковых вопросов. Если у вас есть вопросы по переводам или хотите помогать с ними, то обращайтесь в чат переводчиков. Также можете поддержать нас на OpenCollective.

Данную статью совместными усилиями перевели andreevlex и funkill.

© Habrahabr.ru