Анонс Rust 1.9
Мы рады представить новую версию Rust 1.9. Rust — это системный язык программирования, нацеленный на безопасную работу с памятью, скорость и параллельное выполнение кода.
Как обычно, вы можете установить Rust 1.9 с соответствующей страницы официального сайта, а также ознакомиться с подробным списком изменений в этой версии на GitHub. В этот релиз вошло порядка 1400 патчей.
Что вошло в стабильную версию 1.9
Управляемая размотка стека
Самое большое изменение в Rust 1.9 — стабилизация модуля std::panic
, который
предоставляет методы остановки процесса размотки стека, запущенного паникой:
1 2 3 4 5 6 7 8 9 10 11 | 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’а в другие языки
- Абстракции, управляющие потоками
Первый случай был потенциально неопределённым поведением. На практике размотка в другой язык часто ведёт к сегфолтам. Позволяя ловить панику, мы упрощаем экспорт кода на 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
- Валерий Лашманов