- PVSM.RU - https://www.pvsm.ru -
Мы рады представить новую версию Rust 1.9. Rust — это системный язык программирования, нацеленный на безопасную работу с памятью, скорость и параллельное выполнение кода.
Как обычно, вы можете установить Rust 1.9 [1] с соответствующей страницы официального сайта, а также ознакомиться с подробным списком изменений [2] в этой версии на GitHub. В этот релиз вошло порядка 1400 патчей.
Самое большое изменение в 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 [3].
В общем случае Rust различает два вида ошибочных ситуаций:
Ожидаемые проблемы обычно происходят из-за обстоятельств, которые программа не может контролировать; надёжный код должен быть готов к любой неприятности, возникающей в его окружении. Ожидаемые проблемы обрабатываются в Rust с помощью типа Result
[4], который позволяет функции вернуть вызывающему информацию о проблеме, а вызывающий уже может обработать ошибку. Это довольно точный способ обрабатывать ошибки.
Неожиданные проблемы — это баги: они происходят из-за нарушения контракта или утверждения (assertion). Поскольку их возникновение неожиданно, нет особого смысла в точной обработке таких ошибок. Вместо этого Rust использует подход "fail fast" — такие ошибки вызывают панику, которая по умолчанию начинает размотку стека потока, который столкнулся с ошибкой. При этом исполняются только деструкторы — никакой другой код не выполняется. Другие потоки продолжат выполняться, но обнаружат панику при попытке обменяться данными с паникующим потоком (через каналы или через общую память). Таким образом, паника прерывает исполнение вплоть до какой-то "границы изоляции". Код на другой стороне границы может продолжить работать, и при желании восстановить работу программы из состояния паники, "грубым" образом. Например, сервер не обязательно упадёт из-за проваленного assert'а в одном из своих потоков.
Новый интерфейс catch_unwind
предоставляет способ ввести дополнительные границы изоляции внутри потока. Есть пара примеров, когда это полезно:
Первый случай был потенциально неопределённым поведением. На практике размотка в другой язык часто ведёт к segfault'ам. Позволяя ловить панику, мы упрощаем экспорт кода на Rust в виде API Си — теперь на границе перехода в Си мы можем поймать панику и преобразовать её в код возврата.
Второй случай мотивирован библиотеками пулов потоков. Если поток в пуле паникует, обычно не нужно убивать сам поток. Вместо этого надо поймать панику и сообщить о ней клиенту пула. Интерфейс catch_unwind
имеет парную ему функцию resume_unwind
, которая может быть использована для перезапуска процесса паники на стороне клиента пула, которой она и принадлежит.
В обоих случаях мы вводим дополнительную границу изоляции в пределах потока, и затем преобразуем панику в другой вид ошибки.
Последнее замечание: почему catch_unwind
, а не catch_panic
? Идёт работа [5] по добавлению другой стратегии паникования: прерывание всего процесса (abort). При этом, возможно, будет выполняться общий хук [6]. Для некоторых приложений это наиболее разумный способ обработки ошибок программирования, и предотвращение размотки стека может дать улучшенную производительность и меньший размер кода.
Для авторов библиотек стал доступен новый атрибут: #[deprecated]
. Этот атрибут позволяет отметить устаревший интерфейс, и пользователи библиотеки получат предупреждение при его использовании. При этом можно указать новый рекомендуемый интерфейс на замену. Предупреждения об устаревших интерфейсах давно используются в стандартной библиотеке, а теперь, благодаря RFC 1270 [7], могут быть использованы во всей экосистеме Rust.
Теперь публикуются скомпилированные стандартные библиотеки для нескольких новых платформ:
mips-unknown-linux-musl
,mipsel-unknown-linux-musl
, иi586-pc-windows-msvc
.Первые две платформы особенно интересны с точки зрения кросс-компиляции; см. подробности в недавней публикации о rustup
[8].
Временная сложность проверки переменных на эквивалентность [9] во время унификации типов уменьшена с O(n!) до O(n). В результате этого некоторые образцы кода компилируются намного быстрее.
В этом релизе специализация [10] впервые используется в стандартной библиотеке. В данный момент специализация доступна только на nightly [11]. Она позволяет специализировать обобщённый код для более конкретных типов.
Один из примеров, где это происходит в стандартной библиотеке, это преобразование из среза строки (&str
) в владеемую строку (String
). Метод to_string
берётся из обобщённого интерфейса, который раньше был медленнее, чем специальный метод to_owned
. Теперь эти функции эквивалентны [12].
Реализовав этот простой случай, мы приступим к другим местам, где можно улучшить производительность с помощью специализации.
В 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
. Это исправлено [13] в выпуске 1.9.
В Cargo два больших изменения.
Во-первых, теперь несколько процессов Cargo могут работать одновременно [14].
Во-вторых, добавлен новый флаг — RUSTFLAGS
[15]. Этот флаг позволяет указать произвольные флаги, которые будут передаваться rustc
через окружение. Это полезно, например, для упаковщиков пакетов.
В релизе версии 1.9 участвовало 127 человек. Большое вам спасибо!
Автор: mkpankov
Источник [16]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/programmirovanie/122993
Ссылки в тексте:
[1] установить Rust 1.9: https://www.rust-lang.org/install.html
[2] подробным списком изменений: https://github.com/rust-lang/rust/blob/master/RELEASES.md#version-190-2016-05-26
[3] RFC 1236: https://github.com/rust-lang/rfcs/pull/1236
[4] типа Result
: http://static.rust-lang.org/doc/master/std/result/index.html
[5] работа: https://github.com/rust-lang/rfcs/pull/1513
[6] хук: https://github.com/rust-lang/rfcs/pull/1328
[7] RFC 1270: https://github.com/rust-lang/rfcs/blob/master/text/1270-deprecation.md
[8] подробности в недавней публикации о rustup
: http://blog.rust-lang.org/2016/05/13/rustup.html
[9] Временная сложность проверки переменных на эквивалентность: https://github.com/rust-lang/rust/pull/32062
[10] специализация: https://github.com/rust-lang/rfcs/pull/1210
[11] nightly: http://blog.rust-lang.org/2014/10/30/Stability.html
[12] эквивалентны: https://github.com/rust-lang/rust/pull/32586
[13] исправлено: https://github.com/rust-lang/rust/pull/32054
[14] одновременно: https://github.com/rust-lang/cargo/pull/2486
[15] флаг — RUSTFLAGS
: https://github.com/rust-lang/cargo/pull/2241
[16] Источник: https://habrahabr.ru/post/301994/?utm_source=habrahabr&utm_medium=rss&utm_campaign=best
Нажмите здесь для печати.