Pull to refresh

Анонс Rust 1.9

Reading time 5 min
Views 8.7K
Original author: Rust Core Team

Мы рады представить новую версию Rust 1.9. Rust — это системный язык программирования, нацеленный на безопасную работу с памятью, скорость и параллельное выполнение кода.


Как обычно, вы можете установить Rust 1.9 с соответствующей страницы официального сайта, а также ознакомиться с подробным списком изменений в этой версии на GitHub. В этот релиз вошло порядка 1400 патчей.


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


Управляемая размотка стека


Самое большое изменение в Rust 1.9 — стабилизация модуля std::panic, который предоставляет методы остановки процесса размотки стека, запущенного паникой:


use std::panic;

let result = panic::catch_unwind(|| {
    println!("привет!");
});
assert!(result.is_ok());

let result = panic::catch_unwind(|| {
    panic!("о нет!");
});
assert!(result.is_err());

Этот интерфейс был определён в RFC 1236.


В общем случае Rust различает два вида ошибочных ситуаций:


  • Ожидаемая проблема, например, файл не найден.
  • Неожиданная проблема, например, доступ к массиву вне границ.

Ожидаемые проблемы обычно происходят из-за обстоятельств, которые программа не может контролировать; надёжный код должен быть готов к любой неприятности, возникающей в его окружении. Ожидаемые проблемы обрабатываются в Rust с помощью типа Result, который позволяет функции вернуть вызывающему информацию о проблеме, а вызывающий уже может обработать ошибку. Это довольно точный способ обрабатывать ошибки.


Неожиданные проблемы — это баги: они происходят из-за нарушения контракта или утверждения (assertion). Поскольку их возникновение неожиданно, нет особого смысла в точной обработке таких ошибок. Вместо этого Rust использует подход "fail fast" — такие ошибки вызывают панику, которая по умолчанию начинает размотку стека потока, который столкнулся с ошибкой. При этом исполняются только деструкторы — никакой другой код не выполняется. Другие потоки продолжат выполняться, но обнаружат панику при попытке обменяться данными с паникующим потоком (через каналы или через общую память). Таким образом, паника прерывает исполнение вплоть до какой-то "границы изоляции". Код на другой стороне границы может продолжить работать, и при желании восстановить работу программы из состояния паники, "грубым" образом. Например, сервер не обязательно упадёт из-за проваленного assert'а в одном из своих потоков.


Новый интерфейс catch_unwind предоставляет способ ввести дополнительные границы изоляции внутри потока. Есть пара примеров, когда это полезно:


  • Встраивание Rust'а в другие языки
  • Абстракции, управляющие потоками

Первый случай был потенциально неопределённым поведением. На практике размотка в другой язык часто ведёт к segfault'ам. Позволяя ловить панику, мы упрощаем экспорт кода на Rust в виде API Си — теперь на границе перехода в Си мы можем поймать панику и преобразовать её в код возврата.


Второй случай мотивирован библиотеками пулов потоков. Если поток в пуле паникует, обычно не нужно убивать сам поток. Вместо этого надо поймать панику и сообщить о ней клиенту пула. Интерфейс catch_unwind имеет парную ему функцию resume_unwind, которая может быть использована для перезапуска процесса паники на стороне клиента пула, которой она и принадлежит.


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


Последнее замечание: почему catch_unwind, а не catch_panic? Идёт работа по добавлению другой стратегии паникования: прерывание всего процесса (abort). При этом, возможно, будет выполняться общий хук. Для некоторых приложений это наиболее разумный способ обработки ошибок программирования, и предотвращение размотки стека может дать улучшенную производительность и меньший размер кода.


Предупреждения об устаревших интерфейсах (deprecation warnings)


Для авторов библиотек стал доступен новый атрибут: #[deprecated]. Этот атрибут позволяет отметить устаревший интерфейс, и пользователи библиотеки получат предупреждение при его использовании. При этом можно указать новый рекомендуемый интерфейс на замену. Предупреждения об устаревших интерфейсах давно используются в стандартной библиотеке, а теперь, благодаря RFC 1270, могут быть использованы во всей экосистеме Rust.


Новые платформы для компиляции


Теперь публикуются скомпилированные стандартные библиотеки для нескольких новых платформ:


  • mips-unknown-linux-musl,
  • mipsel-unknown-linux-musl, и
  • i586-pc-windows-msvc.

Первые две платформы особенно интересны с точки зрения кросс-компиляции; см. подробности в недавней публикации о rustup.


Ускорение компиляции


Временная сложность проверки переменных на эквивалентность во время унификации типов уменьшена с O(n!) до O(n). В результате этого некоторые образцы кода компилируются намного быстрее.


Выкатываем использование специализации


В этом релизе специализация впервые используется в стандартной библиотеке. В данный момент специализация доступна только на nightly. Она позволяет специализировать обобщённый код для более конкретных типов.


Один из примеров, где это происходит в стандартной библиотеке, это преобразование из среза строки (&str) в владеемую строку (String). Метод to_string берётся из обобщённого интерфейса, который раньше был медленнее, чем специальный метод to_owned. Теперь эти функции эквивалентны.


Реализовав этот простой случай, мы приступим к другим местам, где можно улучшить производительность с помощью специализации.


Стабилизация библиотек


В 1.9 стабилизированы примерно 80 библиотечных функций. Наиболее заметное изменение — это описанный ранее модуль std::panic. Помимо него есть несколько других вещей.


Работа с сетью


  • TcpStream, TcpListener и UdpSocket получили методы конфигурирования соединения.
  • SocketAddr и его варианты получили удобные методы set_ip() и set_port().

Коллекции


  • BTreeSet и HashSet получили методы take(), replace(), и get(), которые позволяют получить обратно владение исходным ключом.
  • OsString получил несколько новых методов и стал больше похож на String.
  • Срезы получили copy_from_slice(), безопасную форму memcpy.

Кодировки


  • char теперь может быть декодирован в UTF-16.

Указатели


  • Сырые указатели получили as_ref() и as_mut(), которые возвращают Option<&T>, преобразуя нулевые указатели в None.
  • ptr::{read,write}_volatile() позволяют многопоточное (volatile) чтение и запись по сырому указателю.

Наконец, многие типы в libcore не имели реализации типажа Debug. Это исправлено в выпуске 1.9.


Подробнее смотрите здесь.


Возможности Cargo


В Cargo два больших изменения.


Во-первых, теперь несколько процессов Cargo могут работать одновременно.


Во-вторых, добавлен новый флаг — RUSTFLAGS. Этот флаг позволяет указать произвольные флаги, которые будут передаваться rustc через окружение. Это полезно, например, для упаковщиков пакетов.


Подробнее смотрите здесь.


Разработчики версии 1.9


В релизе версии 1.9 участвовало 127 человек. Большое вам спасибо!


Список разработчиков
  • Aaron Turon
  • Abhishek Chanda
  • Adolfo Ochagavía
  • Aidan Hobson Sayers
  • Alan Somers
  • Alejandro Wainzinger
  • Aleksey Kladov
  • Alex Burka
  • Alex Crichton
  • Amanieu d'Antras
  • Andrea Canciani
  • Andreas Linz
  • Andrew Cantino
  • Andrew Horton
  • Andrew Paseltiner
  • Andrey Cherkashin
  • Angus Lees
  • Ariel Ben-Yehuda
  • Benjamin Herr
  • Björn Steinbrink
  • Brian Anderson
  • Brian Bowman
  • Christian Wesselhoeft
  • Christopher Serr
  • Corey Farwell
  • Craig M. Brandenburg
  • Cyryl Płotnicki-Chudyk
  • Daniel J Rollins
  • Dave Huseby
  • David AO Lozano
  • David Henningsson
  • Devon Hollowood
  • Dirk Gadsden
  • Doug Goldstein
  • Eduard Burtescu
  • Eduard-Mihai Burtescu
  • Eli Friedman
  • Emanuel Czirai
  • Erick Tryzelaar
  • Evan
  • Felix S. Klock II
  • Florian Berger
  • Geoff Catlin
  • Guillaume Gomez
  • Gökhan Karabulut
  • JP Sugarbroad
  • James Miller
  • Jeffrey Seyfried
  • John Talling
  • Jonas Schievink
  • Jonathan S
  • Jorge Aparicio
  • Joshua Holmer
  • Kai Noda
  • Kamal Marhubi
  • Katze
  • Kevin Brothaler
  • Kevin Butler
  • Manish Goregaokar
  • Markus Westerlind
  • Marvin Löbel
  • Masood Malekghassemi
  • Matt Brubeck
  • Michael Huynh
  • Michael Neumann
  • Michael Woerister
  • Ms2ger
  • NODA, Kai
  • Nathan Kleyn
  • Nick Cameron
  • Niko Matsakis
  • Noah
  • Novotnik, Petr
  • Oliver Middleton
  • Oliver Schneider
  • Philipp Oppermann
  • Piotr Czarnecki
  • Pyfisch
  • Richo Healey
  • Ruud van Asseldonk
  • Scott Olson
  • Sean McArthur
  • Sebastian Wicki
  • Seo Sanghyeon
  • Simon Sapin
  • Simonas Kazlauskas
  • Steve Klabnik
  • Steven Allen
  • Steven Fackler
  • Stu Black
  • Sébastien Marie
  • Tang Chenglong
  • Ted Horst
  • Ticki
  • Tim Montague
  • Tim Neumann
  • Timon Van Overveldt
  • Tobias Bucher
  • Tobias Müller
  • Todd Lucas
  • Tom Tromey
  • Tshepang Lekhonkhobe
  • Ulrik Sverdrup
  • Vadim Petrochenkov
  • Valentin Lorentz
  • Varun Vats
  • Wang Xuerui
  • Wangshan Lu
  • York Xiang
  • arcnmx
  • ashleysommer
  • bors
  • ggomez
  • gohyda
  • ituxbag
  • mitaa
  • nicholasf
  • petevine
  • pierzchalski
  • pravic
  • srinivasreddy
  • tiehuis
  • ubsan
  • vagrant
  • vegai
  • vlastachu
  • Валерий Лашманов
Tags:
Hubs:
+28
Comments 8
Comments Comments 8

Articles