Команда разработчиков Rust рада сообщить о выпуске новой версии Rust: 1.28.0. Rust — это системный язык программирования, нацеленный на безопасность, скорость и параллельное выполнение кода.


Если у вас установлена предыдущая версия Rust с помощью rustup, то для обновления Rust до версии 1.28.0 вам достаточно выполнить:


$ rustup update stable

Если у вас еще не установлен rustup, вы можете установить его с соответствующей страницы нашего веб-сайта. С подробными примечаниями к выпуску Rust 1.28.0 можно ознакомиться на GitHub.


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


Глобальные аллокаторы


С помощью аллокаторов программы на Rust получают память во время выполнения. Раньше Rust не позволял изменять способ распределения памяти, что ограничивало его использование в некоторых случаях. На одних платформах использовался jemalloc, на других — системный аллокатор, но пользователи не могли это контролировать. В выпуске 1.28.0 стабилизирован атрибут #[global_allocator], который позволяет программам на Rust выбирать системный аллокатор, а также определять новые аллокаторы, реализуя типаж GlobalAlloc.


Аллокатор по умолчанию для Rust-программ на некоторых платформах — это jemalloc. Стандартная библиотека теперь предоставляет дескриптор системного аллокатора, который можно использовать для переключения на использование системного аллокатора, когда это необходимо, путем статического объявления с атрибутом #[global_allocator].


use std::alloc::System;

#[global_allocator]
static GLOBAL: System = System;

fn main() {
    let mut v = Vec::new();
    // Память будет выделяться системным аллокатором.
    v.push(1);
}

Однако, иногда вам требуется определить собственный аллокатор для специфической функциональной области вашего приложения. Это тоже относительно легко сделать, реализовав типаж GlobalAlloc. Подробнее о том, как это сделать, вы можете прочитать в документации.


Улучшено сообщение об ошибке форматирования


Работа по улучшению диагностики продолжается, на этот раз с акцентом на форматирование:


format!("{_foo}", _foo = 6usize);

Раньше сообщение об ошибке в этом месте было довольно скудным:


error: invalid format string: expected `'}'`, found `'_'`
  |
2 |     format!("{_foo}", _foo = 6usize);
  |             ^^^^^^^^

Теперь новое диагностическое сообщение указывает конкретную причину, по которой строка формата недействительна:


error: invalid format string: invalid argument name `_foo`
  |
2 |     let _ = format!("{_foo}", _foo = 6usize);
  |                       ^^^^ invalid argument name in format string
  |
  = note: argument names cannot start with an underscore

Подробности смотрите в примечаниях к выпуску.


Стабилизация стандартной библиотеки


Кроме уже упомянутой стабилизации типажа GlobalAlloc, в этом выпуске стабилизированы NonZero числовые типы. Это типы-обертки вокруг стандартных беззнаковых целочисленных типов: NonZeroU8, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU128 и NonZeroUsize.


Они позволяют оптимизировать размер хранящихся данных. Например, Option<u8> занимает два байта, тогда как Option<NonZeroU8> — один. Обратите внимание, что эта оптимизация сохраняется даже тогда, когда NonZeroU8 завернут внутрь другой структуры; в примере ниже показано, что Door по-прежнему занимает один байт, даже когда он помещен внутрь Option. Эта оптимизация применима также и к перечислениям, определенным пользователем, Option тут не является особенным.


use std::mem;
use std::num::NonZeroU8;

struct Key(NonZeroU8);

struct Door {
    key: Key,
}

fn main() {
    assert_eq!(mem::size_of::<Door>(), 1);
    assert_eq!(mem::size_of::<Option<Door>>(), 1);
}

Также было стабилизировано множество других компонентов библиотеки, полный список которых вы найдете в подробных примечаниях к выпуску.


Улучшения в Cargo


Cargo теперь не позволит вам публиковать пакеты со скриптами сборки, которые модифицируют каталог src. Каталог src в пакете следует считать неизменяемым.


Разработчики 1.28.0


Множество людей участвовало в разработке Rust 1.28. Мы не смогли бы завершить работу без участия каждого из вас. Спасибо!


От переводчика: выражаю отельную благодарность участникам сообщества ruRust и лично ozkriff за помощь с переводом и вычиткой

Комментарии (13)


  1. ozkriff
    06.08.2018 10:13

    Я тут подумал, что на хабре довольно много сочувствующих ржавчине, но не прям сильно следящих за происходящим в экосистеме (не подписанных на TWIR?).
    Так что вот держите очень субъективный срез основных ржавых новостей с за последние шесть недель.


    (Большая часть ссылок ведет на темы в /r/rust, потому что я считаю его главным информационным узлом ржавого сообщества и там в комментариях можно наткнуться на кучу всего занятного.)



    1. freecoder_xx Автор
      06.08.2018 10:22
      +2

      Отличное дополнение!
      Возможно стоило такой обзор отдельным хабропостом сделать. )


      1. Halt
        06.08.2018 11:03
        +2

        Я вообще думаю это стоит делать на регулярной основе. Публикуют же на хабре дайджесты и сборники ссылок. Многим было бы полезно.


  1. DarkEld3r
    06.08.2018 11:22

    А расскажите про аллокаторы поподробнее. Определять #[global_allocator] можно только в конечном бинаре или в либе тоже? И что будет если несколько либ попробуют это сделать?


    1. ozkriff
      06.08.2018 12:33

      Определять #[global_allocator] можно только в конечном бинаре или в либе тоже?

      Можно и в конечном, и в зависимостях (если очень надо):


      It should be emphasized that in most cases, the "terminal" crate (i.e. the bin, cdylib or staticlib crate) should be the only thing selecting the global allocator. Libraries should be agnostic over the global allocator unless they are specifically designed to augment functionality of a specific allocator.

      ( ^ из RFC — http://rust-lang.github.io/rfcs/1974-global-allocators.html )


      И что будет если несколько либ попробуют это сделать?

      Если во всей сборке (включая и твой пакет, и все зависимости) есть больше одного #[global_allocator], то сборка сразу грохается, даже если используются одинаковые типы. Пример сообщения при наличии двух пакетов a и b, переопределяющих аллокаторы на системный:


      error: the #[global_allocator] in a conflicts with this global allocator in: b


      1. DarkEld3r
        06.08.2018 15:45

        Спасибо.


        Хотя возможность определять аллокаторы в либах всё-таки (для меня) выглядит странно, но может это от недопонимания.


  1. forcam
    06.08.2018 12:42
    -1

    Rust — это самое прекрасное, что создавалось с момента возникновения Assembler))


    1. nlinker
      08.08.2018 20:06

      Не понимаю, за что минусы, но может хаскелисты обиделись… :-)


  1. slee_ping
    08.08.2018 00:42
    +1

    Синтаксис конечно жесток, КАК ПО МНЕ, но в будущем, думаю начать «ржаветь» :)


  1. DelphiCowboy
    08.08.2018 00:42

    Как с поддержкой OpenGL?



    1. ozkriff
      08.08.2018 14:38

      Если хочется максимально прямой и unsafe доступ к OpenGL, то есть пакет gl-rs.


      Если хочется "более ржавого" GL, то обычно вспоминают о двух пакетах: glium и gfx-rs.


      При этом наблюдается уход от OpenGL в сторону Вулкана — glium автор вообще перевел в режим зомби, полностью переключившись на работу над vulkano, а gfx переживает масштабное переписывание, что бы быть ближе к новым низкоуровневыми апи и OpenGL бэкенд будет поддерживаться только как "второсортный".


      1. ozkriff
        08.08.2018 14:47

        А, еще забыл https://github.com/phaazon/luminance-rs. У него есть занятное и относительно непредвзятое сравнение с альтерантивами: https://phaazon.net/blog/luminance_comparing