Выпуск Rust 1.20
• оригинал: The Rust Core Team • перевод: red75prime и Илья Богданов • новости • поддержите на Patreon
Команда Rust рада представить выпуск Rust 1.20. Rust — это системный язык программирования, нацеленный на скорость, безопасность и параллельное выполнение кода.
Если у вас установлена предыдущая версия Rust, для обновления достаточно выполнить:
1 | $ rustup update stable
|
Если же Rust ещё не установлен, вы можете установить rustup
с соответствующей
страницы нашего веб-сайта и ознакомится с подробными примечаниями к выпуску Rust 1.20 на GitHub.
Что вошло в стабильную версию 1.20
В предыдущих версия Rust вы могли определять типажи, структуры и перечисления, имеющие «ассоциированные функции»:
1 2 3 4 5 6 7 8 9 10 11 | struct Struct; impl Struct { fn foo() { println!("foo - это ассоциированная функция для Struct"); } } fn main() { Struct::foo(); } |
Мы называем их «ассоциированными функциями», потому что эти функции связаны непосредственно с самим типом, а не с каким-то определённым экземпляром.
В Rust 1.20 была добавлена возможность определять «ассоциированные константы»:
1 2 3 4 5 6 7 8 9 | struct Struct; impl Struct { const ID: u32 = 0; } fn main() { println!("the ID of Struct is: {}", Struct::ID); } |
Таким образом, константа ID
ассоциирована с Struct
.
Подобно функциям, ассоциированные константы работают и с типажами, и с перечислениями.
У типажей есть дополнительная возможность, полезная во многих ситуациях. Вы можете использовать ассоциированные константы также, как и ассоциированные типы: объявляя их, но не назначая никакого значения. Конкретное значение должно быть назначенным во время реализации типажа каким-либо типом.
1 2 3 4 5 6 7 8 9 10 11 12 13 | trait Trait { const ID: u32; } struct Struct; impl Trait for Struct { const ID: u32 = 5; } fn main() { println!("{}", Struct::ID); } |
До этого выпуска, если вы хотели написать типаж, представляющий числа с плавающей точкой, вам приходилось делать так:
1 2 3 4 5 | trait Float { fn nan() -> Self; fn infinity() -> Self; ... } |
Это выглядит немного громоздко, но, что важнее, мы не могли использовать эти функции в константных выражениях, даже если функции и возвращали одно и то же значение.
Из-за этого, Float
также должен предоставлять и константы:
1 2 3 4 5 6 7 8 9 10 11 12 13 | mod f32 { const NAN: f32 = 0.0f32 / 0.0f32; const INFINITY: f32 = 1.0f32 / 0.0f32; impl Float for f32 { fn nan() -> Self { f32::NAN } fn infinity() -> Self { f32::INFINITY } } } |
Ассоциированные константы позволяют сделать вам то же самое, но гораздо легче. Объявление типажа:
1 2 3 4 5 | trait Float { const NAN: Self; const INFINITY: Self; ... } |
Реализация:
1 2 3 4 5 6 | mod f32 { impl Float for f32 { const NAN: f32 = 0.0f32 / 0.0f32; const INFINITY: f32 = 1.0f32 / 0.0f32; } } |
гораздо понятнее и более гибко.
Ассоциированные константы были предложены в RFC 195, почти три года назад. Приличный срок! Тот RFC содержал все виды ассоциированных элементов, а не только константы. Некоторые из них мы смогли реализовать быстрее чем другие. Мы много работаем над улучшением поддержки работы с константными выражениями, чтобы увеличить возможности Rust в области мета-программирования во время компиляции. В будущем в этой области появятся дополнительные возможности.
Кроме того, мы исправили ошибку при работе с макросом include!
в тестах документации: пути к файлам определялись относительно рабочего каталога, а не каталога, в котором находится текущий файл.
Смотрите детальные заметки к выпуску для подробностей.
Стабилизация стандартной библиотеки
Никаких супер выдающихся изменений в этом релизе нет, только несколько полезных улучшений и продолжение работы над стабилизацией стандартной библиотеки.
Макрос unimplemented!
теперь принимает параметр, позволяющий сообщить пользователю, по какой причине что-либо не было реализовано.
Мы обновили поддержку Unicode до версии 10.0.0.
Функции min
и max
у типов с плавающей запятой были переписаны на Rust, и больше не зависят от cmath
.
Внедрена защита от уязвимости Stack Clash. Основные изменения: stack probes и отключение дополнительных ручных проверок для стека основного потока на Linux. Для включения защиты достаточно скомпилировать проект в Rust 1.20, изменения в коде не требуются.
В стандартную библиотеку добавлены три новые функции сортировки: slice::sort_unstable_by_key
, slice::sort_unstable_by
и slice::sort_unstable
. Как вы заметили, все три содержат «unstable» в названиях. Стабильность — это свойство алгоритма сортировки, которое требуется не всегда, но раньше в стандартной библиотеке не было алгоритмов нестабильной сортировки. Теперь доступны обе возможности! Для демонстрации разницы между этими видами сортировки рассмотрим список:
1 2 3 4 | rust crate package cargo |
Два слова из приведённых, cargo
и crate
, начинаются с буквы c
. Список, отсортированный алгоритмом стабильной сортировки только по первой букве, должен выглядеть таким образом:
1 2 3 4 | crate cargo package rust |
То есть, если в исходном списке слово crate
предшествовало слову cargo
, то и в отсортированном списке оно должно стоять первым. Алгоритм нестабильной сортировки тоже может выдать такой результат, но допускается и вариант с изменённой последовательностью:
1 2 3 4 | cargo crate package rust |
Как вы понимаете, меньшее количество ограничений часто позволяет создать более быстрый алгоритм. Если вам не важна стабильность сортировки, нестабильная сортировка может оказаться быстрее, чем стабильный вариант. Как обычно, лучше попробовать оба варианта и сравнить их скорость. Эти функции сортировки были добавлены в RFC 1884. По ссылке вы можете узнать больше подробностей, включая результаты бенчмарков.
Также были стабилизированы следующие API:
CStr::into_c_string
CString::as_c_str
иCString::into_boxed_c_str
Chain::get_mut
,Chain::get_ref
, иChain::into_inner
Option::get_or_insert_with
иOption::get_or_insert
OsStr::into_os_string
OsString::into_boxed_os_str
Take::get_mut
иTake::get_ref
Utf8Error::error_len
char::EscapeDebug
иchar::escape_debug
compile_error!
f32::from_bits
иf32::to_bits
f64::from_bits
иf64::to_bits
mem::ManuallyDrop
str::from_boxed_utf8_unchecked
str::as_bytes_mut
str::from_utf8_mut
иstr::from_utf8_unchecked_mut
str::get_unchecked
иstr::get_unchecked_mut
str::get
иstr::get_mut
str::into_boxed_bytes
Смотрите детальные заметки к выпуску для подробностей.
Улучшения Cargo
Этот релиз внёс полезные улучшения в менеджер пакетов cargo. Первое и самое важное: токен аутентификации для crates.io
хранился в ~/.cargo/config
. Обычно маска доступа для файлов конфигурации имеет значение 644
, то есть чтение разрешено всем пользователям. Однако, в этом файле хранился секретный токен. Мы переместили его в отдельный файл ~/.cargo/credentials
, для которого может быть установлена маска доступа 600
, и он будет скрыт от других пользователей системы.
Если вы использовали пакеты Cargo, создающие дополнительные исполняемые файлы, вы знаете, что их исходный код хранится в src/bin
. Но иногда вам может понадобиться создать несколько дополнительных исполняемых файлов, требующих много кода. В этом случае код может храниться в файлах src/bin/client.rs
и src/bin/server.rs
, и все подмодули этих файлов попадут в один каталог, что неудобно и создаёт путаницу. Теперь мы используем соглашение, по которому такие файлы как src/bin/server/main.rs
и src/bin/client/main.rs
также используются для создания дополнительных исполняемых файлов. Это позволяет удобнее разграничить код.
Смотрите детальные заметки к выпуску для подробностей.
Разработчики 1.20.0
Множество людей участвовало в разработке Rust 1.20. Мы не смогли бы этого добиться без участия каждого из вас. Спасибо!