Выпуск языка программирования Rust 1.34

Состоялся релиз языка системного программирования Rust 1.34, развиваемого проектом Mozilla. Язык сфокусирован на безопасной работе с памятью, обеспечивает автоматическое управление памятью и предоставляет средства для достижения высокого параллелизма выполнения заданий, при этом обходясь без использования сборщика мусора и runtime.

Автоматическое управление памятью в Rust избавляет разработчика от манипулирования указателями и защищает от проблем, возникающих из-за низкоуровневой работы с памятью, таких как обращение к области памяти после её освобождения, разыменование нулевых указателей, выход за границы буфера и т.п. Для распространения библиотек, обеспечения сборки и управления зависимостями проектом развивается пакетный менеджер Cargo, позволяющий получить нужные для программы библиотеки в один клик. Для размещения библиотек поддерживается репозиторий crates.io.

Основные новшества:

  • В пакетный менеджер Cargo добавлены средства для работы с альтернативными реестрами пакетов, которые могут сосуществовать с публичным реестром crates.io. Например, разработчики закрытых приложений теперь могут использовать собственный приватный реестр, который можно использовать при перечислении зависимостей в Cargo.toml, и применять для своих продуктов модель версионирования, схожую с crates.io, а также ссылаться в зависимостях как на crates.io, так и на собственный реестр.

    Для добавления внешнего реестра в ~/.cargo/config в секции »[registries]» предусмотрена новая опция «my-registry», а для упоминания внешнего реестра в зависимостях в Cargo.toml в секции »[dependencies]» появилась опция «other-crate». Для подключения к дополнительному реестру достаточно поместить токен аутентификации в файл ~/.cargo/credentials и выполнить команду «cargo login --registry=my-registry», а для публикации пакета — «cargo publish --registry=my-registry»;

  • Добавлена полноценная поддержка использования оператора »?» в тестах doctests, позволяющих использовать код примеров из документации в качестве тестов. Ранее оператор »?» можно было использовать для обработки ошибок в процессе выполнения тестов только при наличии функции «fn main ()» или в функциях »#[test]»;
  • В определяемых при помощи процедурных макросов собственных атрибутах (custom attribute) обеспечена возможность использования произвольных наборов токенов (»#[attr ($tokens)]»,»#[attr[$tokens]] и #[attr{$tokens}]»). Ранее элементы могли задаваться только в древовидном/рекурсивном виде c использованием строковых литералов, например »#[foo (bar, baz (quux, foo = «bar»))]», а теперь возможно использование перечислений ('#[range (0…10)]') и конструкций вида »#[bound (T: MyTrait)]»;
  • Стабилизированы типажи (trait) TryFrom и TryInto, позволяющие выполнять преобразования типов с обработкой ошибок. Например, методы, подобные from_be_bytes, с целочисленными типами в качестве входных данных используют массивы, но данные часто поступают c типом Slice, а преобразование между массивами и слайсами проблематично делать вручную. При помощи новых типажей указанная операция может быть совершена на лету через вызов .try_into (), например, «let num = u32:: from_be_bytes (slice.try_into ()?)». Для преобразований, которые всегда завершаются успешно (например, из типа u8 в u32) добавлен тип ошибок Infallible, позволяющий прозрачно использовать TryFrom для всех существующих реализаций «From»;
  • Объявлена устаревшей функция CommandExt: before_exec, позволявшая выполнить обработчик перед запуском exec, который выполнялся в контексте дочернего процесса, ответвлённого после вызова fork (). В подобных условиях некоторые ресурсы родительского процесса, такие как файловые дескрипторы и отражённые области памяти, могли быть дублированы, что могло привести к неопределённому поведению и неверной работе библиотек. Вместо before_exec рекомендуется использовать unsafe-функцию CommandExt: pre_exec.
  • Стабилизированы знаковые и беззнаковые атомарные целочисленные типы размером от 8 до 64 бит (например, AtomicU8), а также знаковые типы NonZeroI[8×16|32×54|128].
  • В разряд стабильных переведена новая порция API, в том числе стабилизированы методы Any: type_id, Error: type_id, slice: sort_by_cached_key, str: escape_*, str: split_ascii_whitespace, Instant: checked_[add|sub] и SystemTime: checked_[add|sub]. Стабилизированы функции iter: from_fn и iter: successors;
  • Для всех целочисленных типов реализованы методы checked_pow, saturating_pow, wrapping_pow и overflowing_pow;
  • Добавлена возможность включения оптимизаций на этапе связывания через указание сборочной опции »-C linker-plugin-lto» (rustc компилирует код Rust в биткод LLVM, что позволяет применить LTO-оптимизации).

© OpenNet