[Перевод] Выпуск Rust 1.39.0: async/await, аттрибуты для параметров функций, новые константные функции

?v=1

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

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

$ rustup update stable

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


Что вошло в стабильную версию 1.39.0

Наиболее существенные нововведения включают в себя синтаксис async/.await, разделяемые ссылки к перемещаемым значениям в match-guards и атрибуты у параметров функций. Смотрите подробные примечания к выпуску для дополнительной информации.


С .await закончено, встречайте async fn

Ранее в Rust 1.36.0 мы объявили о доступности трейта Future. Тогда же мы отметили, что:


Мы надеемся, что это нововведение позволит популярным крейтам, библиотекам и в целом всей экосистеме подготовиться к синтаксису async/.await, стабилизация которого планируется на недалёкое будущее.

Обещание дано — обещание выполнено. Мы рады объявить, что долгожданный синтаксис async/.await, позволяющий определять асинхронные функции и блоки (async) и ожидать их выполнения (.await), наконец стабилизирован!

Асинхронная функция, определяемая посредством синтаксиса async fn (вместо обычного fn), ничего не делает кроме того, что при вызове возвращает объект, реализующий трейт Future. Данный объект является приостановленным вычислением, завершить которое можно синтаксисом .await. Кроме того, async fn, async { ... } и async move { ... } действуют как замыкания и могут использоваться для определения асинхронных литералов.

Подробнее о выпуске async/.await можете почитать в посте блога Niko Matsakis.


Разделяемые ссылки к перемещаемым значениям в match-guards

При сопоставлении с образом переменную, известную как «байндинг» (binding), можно привязать одним из следующих способов:


  • По ссылке, неизменной или изменяемой. Это можно сделать явно, например, синтаксисом ref my_var или ref mut my_var соответственно. Почти всегда режим привязки будет выведен автоматически.


  • По значению — либо копированием (если тип привязанной переменной реализует трейт Copy), либо передачей во владение.


Ранее Rust запрещал взятие совместных ссылок (shared references) на переменные-привязки во владение в коде с if при наличии (guards) выражения match. Таким образом, что следующий код был бы отвергнут:

fn main() {
    let array: Box<[u8; 4]> = Box::new([1, 2, 3, 4]);

    match array {
        nums
//      ---- `nums` привязан с владением (by move).
            if nums.iter().sum::() == 10
//                 ^------ `.iter()` берется явная ссылка на `nums`
        => {
            drop(nums);
//          ----------- `nums` привязан и в нашем владении
        }
        _ => unreachable!(),
    }
}

Начиная с Rust 1.39.0, фрагмент выше компилятор примет без предупреждений и ошибок. Надеемся, что это нововведение повысит удобство использования выражения match.


Атрибуты для параметров функций

Начиная с Rust 1.39.0, атрибуты стало можно применять для параметров, замыканий и указателей на функции. Раньше функция len() могла быть представлена следующим образом:

#[cfg(windows)]
fn len(slice: &[u16]) -> usize {
    slice.len()
}
#[cfg(not(windows))] 
fn len(slice: &[u8]) -> usize {
    slice.len()
}

Но Rust 1.39.0 позволяет написать приведённый выше код значительно проще:

fn len(
    #[cfg(windows)] slice: &[u16], // Этот параметр будет использован в операционной системе Windows.
    #[cfg(not(windows))] slice: &[u8], // В остальных случая будет использован этот параметр.
) -> usize {
    slice.len()
}

Атрибуты, пригодные к использованию, включают в себя:


  1. условную компиляцию: cfg и cfg_attr;


  2. управление проверками: allow, warn, deny и forbid;


  3. вспомогательные атрибуты, используемые процедурными макросами-атрибутами для элементов синтаксиса.

    Надеемся, что данное нововведение поможет экосистеме в написании более выразительных DSL, основанных на макросах.



Миграционные предупреждения проверки заимствований становятся серьёзными ошибками в Rust 2018

В релизе 1.35.0 мы анонсировали, что новый анализатор заимствований (NLL) пришёл в редакцию Rust 2015 после того, как был выпущен для редакции Rust 2018 в версии 1.31.

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

Начиная с Rust 1.39.0, эти предупреждения теперь являются ошибками в редакции Rust 2018.
В следующем релизе Rust 1.40.0, данное правило также будет применятся к коду редакции Rust 2015, что позволит полностью устранить старый анализатор заимствований из компилятора.

Если вас затронули эти изменения, или вы хотите узнать больше, почитайте пост в блоге Niko Matsakis.


Больше константных функций в стандартной библиотеке

Начиная с Rust 1.39.0, следующие функции помечены как константные (const fn):


  • [Vec::new], [String::new] и [LinkedList::new];
  • [str::len], [T]::len и [str::as_bytes];
  • [abs], [wrapping_abs] и [overflowing_abs].


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

В Rust 1.39.0 были стабилизированы следующие функции:


  • [Pin::into_inner]
  • [Instant::checked_duration_since] и [Instant::saturating_duration_since]


Другие изменения

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

Пожалуйста, прочтите заметки о совместимости, чтобы узнать, затронут ли вас эти изменения.


Участники 1.39.0

Множество людей собрались вместе, чтобы создать Rust 1.39.0. Мы не смогли бы сделать это без всех вас, спасибо!


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

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

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

© Habrahabr.ru