LINUX.ORG.RU

Rust 1.27

 


3

10

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

Основные изменения:

  • SIMD — наиболее значимое и ожидаемое нововведение: стабильная версия Rust обзавелась базовой поддержкой SIMD.
    Для примера использования рассмотрим следующий сниппет:
    pub fn foo(a: &[u8], b: &[u8], c: &mut [u8]) {
        for ((a, b), c) in a.iter().zip(b).zip(c) {
            *c = *a + *b;
        }
    }
    
    Здесь мы берем два слайса, складываем числа в них и помещаем результат в третий слайс. Самый простой способ, описанный выше — это проход в цикле по каждому слайсу, сложение и сохранение результата. Впрочем, это можно сделать быстрее и в LLVM может автовекторизовать такой код, подставив SIMD инструкции автоматически.

    Стабильный Rust уже давно использует возможности автовекторизации LLVM, но, к сожалению, компилятор может использовать подобные оптимизации не всегда. В Rust 1.27.0 добавлен модуль std::arch, включающий базовую поддержку использования инструкций SIMD напрямую из кода на Rust. Кроме того, добавлены соответствующие директивы условной компиляции:

    #[cfg(all(any(target_arch = "x86", target_arch = "x86_64"),
          target_feature = "avx2"))]
    fn foo() {
        #[cfg(target_arch = "x86")]
        use std::arch::x86::_mm256_add_epi64;
        #[cfg(target_arch = "x86_64")]
        use std::arch::x86_64::_mm256_add_epi64;
    
        unsafe {
            _mm256_add_epi64(...);
        }
    }
    
    В примере выше флаги cfg позволяют выбрать правильную версию функции в зависимости от целевой архитектуры во время компиляции. Также мы можем это сделать в рантайме:
    fn foo() {
        #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
        {
            if is_x86_feature_detected!("avx2") {
                return unsafe { foo_avx2() };
            }
        }
    
        foo_fallback();
    }
    

    Примитивы, включенные в стандартную библиотеку обеспечивают минимальную поддержку и весьма низкоуровневы, но их включение позволяет развивать более выкокоуровневые примитывы в библиотеках. К примеру, крейт faster предоставляет удобный интерфейс, основанный на концепции итераторов.

    Без SIMD

    let lots_of_3s = (&[-123.456f32; 128][..]).iter()
        .map(|v| {
            9.0 * v.abs().sqrt().sqrt().recip().ceil().sqrt() - 4.0 - 2.0
        })
        .collect::<Vec<f32>>();
    

    С SIMD (faster)

    let lots_of_3s = (&[-123.456f32; 128][..]).simd_iter()
        .simd_map(f32s(0.0), |v| {
            f32s(9.0) * v.abs().sqrt().rsqrt().ceil().sqrt() - f32s(4.0) - f32s(2.0)
        })
        .scalar_collect();
    

  • dyn Trait

    Изначальный синтаксис трейт-объектов в Rust — одна из тех вещей, о введении которых мы жалеем: для некоторого трейта Foo, его трейт-объект будет выглядеть так: Box<Foo>

    И если Foo является структурой, синтаксис аллокации структуры в «куче» будет выглядеть точно так же.

    Когда язык разрабатывался, казалось что сходство здесь уместно, но опыт показал, что это только путает людей.

    То же самое справедливо для случая impl SomeTrait for SomeOtherTrait, что является корректным синтаксисом, но интуитивно понимается как реализация трейта SomeTrait для всех типов, реализующих SomeOtherTrait, но на самом деле это записывается как impl<T> SomeTrait for T where T: SomeOtherTrait, в то время как первый вариант является реализацией трейта для трейт-объекта.

    Кроме того, появление impl Trait в противовес Trait ввело некую неконсистентность при обучении языку.

    Исходя из этого, в Rust 1.27 мы стабилизируем новый синтаксис dyn Trait.
    Теперь трейт-объейты выглядят так:

    // old => new
    Box<Foo> => Box<dyn Foo>
    &Foo => &dyn Foo
    &mut Foo => &mut dyn Foo
    

    То же самое применимо к другим типам указателей:
    Arc<Foo> теперь объявляется как Arc<dyn Foo>.

    Исходя из требований к обратной совместимости, мы не можем удалить старый синтаксис, но мы добавили предупреждение компилятора, призывающее обновить синтаксис для трейт-объектов. Пока что оно выключено по умолчанию.

  • #[must_use] для функций
    Наконец, атрибут #[must_use] получил новые возможности: теперь он применим к функциям.

    Раньше он использовался только на типах, таких как Result<T, E>, где возвращаемое значение должно быть использовано, но теперь возможно такое применение:

    #[must_use]
    fn double(x: i32) -> i32 {
        2 * x
    }
    
    fn main() {
        double(4); // warning: unused return value of `double` which must be used
    
        let _ = double(4); // (no warning)
    }
    

    Также этот атрибут был добавлен к некоторым функциям в стандартной библиотеке, таким как Clone::clone, Iterator::collect и ToOwned::to_owned, теперь компилятор предупредит в случае, если их результат останется неиспользованным, что поможет заметить и предотвратить случайный вызов затратных операций.

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

Новые возможности Cargo

В текущем релизе в Cargo включены два маленьких нововведения:

Во-первых, Cargo теперь принимает флаг --target-dir.

Во-вторых, Cargo теперь будет пытаться автоматически найти тесты, примеры и исполняемые файлы (прим. бинарные подпроекты в библиотечных крейтах) в проекте, но явная конфигурация всё же будет требоваться в некоторых случаях.

Для помощи в конфигурации мы добавили несколько ключевых слов в Cargo.toml.

Обновить Rust можно с помощью команды:

curl https://sh.rustup.rs -sSf | sh # если у вас еще не установлен rustup
rustup update stable

>>> Подробности

★★★★★

Проверено: tailgunner ()
Последнее исправление: cetjs2 (всего исправлений: 5)

Ответ на: комментарий от anonymous

Откуда мне знать. У меня не работает на новом проекте с чистой установкой. Идеальные условия, казалось бы, а он лажает. Не готов.

RazrFalcon ★★★★★
()
Ответ на: комментарий от RazrFalcon

Мне Nuklear/Factor::ui хватает.


от GTK+ только виджет главного окна

Элементы разные, кнопки. Но не суть, им хватает. А зачем тащить Qt во все проекты?

linuhs_user
()
Последнее исправление: linuhs_user (всего исправлений: 1)
Ответ на: комментарий от RazrFalcon

Ну давай, расскажи, что умеет Qt такого, чего не сделать на GTK. Кстати, использовать Qt с нормальными языками по-прежнему почти невозможно. И поделие, гвоздями приколоченное к плюсоубожеству — в 2018 ничего кроме смеха не вызывает. А тред про Rust.

anonymous
()
Ответ на: комментарий от anonymous

Одно удручает, что всем заправляют оголтелые SJW из Мозиллы, CoC в каждое дырку, удаление «негативных» дискуссиий, всем надеть намордники и радоваться.

anonymous
()
Ответ на: комментарий от RazrFalcon

Нужно сразу анальный SaaS

Вообще-то идея отличная. Хороший пример - syncthing. В одном бинарнике собственно логика приложения и http-сервер с веб-приложением

А вот реализации подкачивают. На C++ наверное проблема с веб-фреймворками - поэтому не пишут. А на динамических языках пишут так, что тебуется еще дюжину сервисов настроить чтоб запустилось (ngnx, mysql, redis, ..). Вспоминаю как всю ночь про****ся с NextCloud и Seafile - так и не настроил. Вернулся на syncthing. Простота использования для конечного юзера решает

makoven ★★★★★
()
Последнее исправление: makoven (всего исправлений: 1)

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

автору статьи спасибо за раздачу.

anonymous
()
Ответ на: комментарий от makoven

Речь не о редакторах, а об IDE. Например JetBrains принципиально не собираются использовать RLS. Кроме того они не поддерживают дебагер кроме как в платном CLion.

bbk123 ★★★★★
()
Ответ на: комментарий от bbk123

IDE - это древнее африканское слово, означающее «жаба не тормозит, купи себе памяти, нищеброд».

anonymous
()
Ответ на: комментарий от makoven

Простота использования для конечного юзера решает

Поэтому я использую dropbox.

RazrFalcon ★★★★★
()
Ответ на: комментарий от linuhs_user

А зачем тащить Qt во все проекты?

Потому, что альтернатив нет. Ваш КО.

RazrFalcon ★★★★★
()
Ответ на: комментарий от anonymous

Вот и африканские линуксоиды с проблемами в умственном развитии подтянулись.

bbk123 ★★★★★
()
Ответ на: комментарий от RazrFalcon

Чё сразу не Tk?

То есть по делу возразить нечего? Сразу распальцовка и чёканье. Так и запишем: Lazarus победил и аргументов против его использования, для написания гуя, нет

anonymous
()
Ответ на: комментарий от anonymous

То есть это я виноват в том, что ваш любимый язычок никто не использует? Ну ок.

PS: В одних кедах больше прог, чем по ссылкам.

RazrFalcon ★★★★★
()
Ответ на: комментарий от anonymous

Либо чтобы растеры могли чувствовать себя «не такими как все». В такое не факт, что и плюсовый разраб захочет лезть. Лично я абсолютно не способен это читать, ибо многие отбитые растеры любят фигачить в строку, при этом в расте не обязательны ретурны.

WitcherGeralt ★★
()
Ответ на: комментарий от WitcherGeralt

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

anonymous
()
Ответ на: комментарий от anonymous

А почему нет? Посмотри на Go, мало того, что он простой сам по себе, так там ещё и по стилю всё строго. За счёт этого практически любой код одинаково хорошо читается, ну и да, там рулят табы, и это прекрасно.

WitcherGeralt ★★
()
Ответ на: комментарий от WitcherGeralt

В го нет и половины того, что есть в Rust, это сравнение бессмысленно. Ну и как по мне Rust читается намного легче Go благодаря правильным абстракциям.

Nexmean
()
Ответ на: комментарий от WitcherGeralt

Go — не только простой, он примитивный. Топорная поделка из прошлого, созданная, чтобы корпоративные макаки не путались в трёх скобках. Кому как, но по мне, пользоваться этим — весьма уныло. И да, табы это хорошо. Пробелодебилы идут лесом.

anonymous
()
Ответ на: комментарий от Nexmean

Они плюс идеологически разные. Rust — полноценный язык, с конкретной и серьёзной нишей, где не боятся, что очередная обезьяна перепутает символы. А Go — это чтобы обезьян заранее в клетке держать.

anonymous
()
Ответ на: комментарий от RazrFalcon

Electron для слабаков. Нужно сразу анальный SaaS.

Почему Electron для слабаков? Корпорация Microsoft отличный текстовый редактор сделала на Electron. Ну не Qt же ей было для это брать, в самом то деле. Лол.

azelipupenko
()
Ответ на: комментарий от anonymous

В жидхабе мамкиного борщехлёба?

anonymous
()
Ответ на: комментарий от WitcherGeralt

практически любой код одинаково хорошо читается

m := map[string]*data {"x":{"one"}}
data := []*struct{num int} {{1},{2},{3}}
func (r *rect) area() int {
RazrFalcon ★★★★★
()
Ответ на: комментарий от anonymous

Мой родной язык - русский, но в отличии от вас я не пытаюсь судить о читаемости языков, которые я не знаю.

Nexmean
()
Ответ на: комментарий от Nexmean

Тем, что все плагины работают через одно место и медленно. Плюс там ограничение на 251 подчёркнутое слово.

RazrFalcon ★★★★★
()

Эххх... embedded-wg как-то без прорывов пока.

Очень не хватает async/await в HAL на блочные операции с периферией, и RTFM с новыми фичами по отправке сообщений.

Vit ★★★★★
()
Ответ на: комментарий от WitcherGeralt

В русте стиль тоже строгий, cargo fmt, все дела. Но го слишком уж многословный, вот сравни-ка

Го:

func operation() int, error {
    res1, err := subop1()
    if err != nil {
        return err
    }
    res2, err := subop2(res1)
    if err != nil {
        return err
    }
    return res2
}

Rust

fn operation() -> Result(u8, SomeErrorType) {
    let res1 = subop1()?;
    let res2 = subop2(res1)?;
    res2
}
provaton ★★★★★
()
Ответ на: комментарий от provaton

Именно поэтому на Go есть работа и он популярен, а раст так и остался маргинальным языком с маргинальным сообществом.

anonymous
()

Чем он лучше Qt?

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.