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)
Ответ на: комментарий от Crocodoom

Ну-у-у Перловка да, похожа на Баш. Примерно как c++17 на c89.

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

Примеров?

Не только. Иногда (но не всегда!) код в одну строчку будет читаться лучше

Нахерачат там анонимных функций

Ну в Rust синтаксис анонимных функций не так уж и плох, а по сравнению с Go — он вообще шикраный и его никто не должен боятся.
Кроме того, функциональный подход очень удобный для решения некоторых задач

начейнят

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

а часть из этого таки перенесут...

Иногда так группируют логически связанные вызовы

глаза поломаешь это читать.

Доля правды в этом всё-таки есть...

Ага, Gas тоже норм читается.

Gas?

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

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

есть. если, конечно, дать переменной вменяемое имя, а не a= b= c=

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

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

есть. если, конечно, дать переменной вменяемое имя

Ага. intermediate_result_1, intermediate_result_2, intermediate_result_3 и так далее.

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

Какие настройки? Сначала найди нужный файл в их наркоманских темах, лол. Адвайта так вовсе захардкожена в бинарях и с,ней номер не пройдет. Короче, гугли и дерзай. Или терпи дефолт.

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

Компилер с xmpp не совсем корректно сравнивать

шкет, я видел тебя, когда у тебя ещё звёзд не было.

я сравниваю не компилятор и хмпп, а разработку стандартов. я точно так же мог бы сравнить C/C++ и Rust: если ты не заметил, в отличии от Rust, ВСЕ стандарты C/C++ являются не версионироваными, а отдельными, и предыдущие (не версии, заметь, а) стандарты, не становятся и не являются депрекейтед.

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

Сразу видно молодого человека, который не застал iostream.h и gcc-2.75.

Ой да ладно, не было никакого gcc 2.75. Был gcc 2.95 - пререлиз (очень ранний пререлиз gcc 3.0, реальный номер версии был 2.96, ЕМНИП), который Redhat выпустил по собственной инициативе.

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

Сразу видно молодого человека, который не застал iostream.h и gcc-2.75.

мне тебя как обозвать, за неумение отделять стандарт и реализацию? g++ != [список наименований стандартов C++]

и спецификацию (вряд ли когда-нить доживёт до стандартизации) Rust, может реализовать другая компания, если рискнёт гнаться за группкой, которая гнёт спеку под реализацию, а не наоборот.

а вот реализаций C++ - хоть жопой жуй, как ты, наверное, заметил.

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

и спецификацию (вряд ли когда-нить доживёт до стандартизации) Rust, может реализовать другая компания, если рискнёт гнаться за группкой, которая гнёт спеку под реализацию, а не наоборот.

Спека всегда гнется под реализацию (если это не спека SML, конечно).

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

Но у раста нет никакой спеки. Кто там кого гнёт? Мазила говнокодит в свое удовольствие и всё. Если делать спеку, нужно сразу половину говнофич выбрасывать (вместе с мазилой).

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

Загуглил как расшифровывается RFC, орнул. Так-то пост любой инстаграм-дивы это RFC

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

gcc 2.95

Циферки за давностью лет спутал.

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

Комитет попытался протолкнуть в реализации export template, реализаторы дружно его послали, комитет прогнулся.

нет, это не тоже самое: если что-то прошло в спеку, то это прошло стадию оговаривания и всеобщего согласования.

ещё попытки?

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

export template был в стандарте C++ где-то с 2000-го года и по C++11, все забили. Спеку подогнали под реализации, что не нравится?

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

Количество усилий, затрачиваемое на оптимизацию компилятора, впечатляет

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

GNU Assembler, — не самый недружелюбный вариант асма.

Как-бы да
Но по большому счету, они все достаточно недружелюбные - в том смысле, что для его использования всегда требуется головной мозг

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

Нет. В расте эти закорючки обоснованы. А у баша с питоном нет подобных, жестких требований, поэтому они могут иметь простой синтаксис.

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

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

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

Это сарказм, конечно. Как по поводу полезности имен для промежуточных результатов, так и по поводу их вменяемости IRL.

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

примеры? пруфлинки?

Всё развитие Си++ до 1992 года (референсная реализация, которую Страуструп пилил, как хотел); развитие шаблонов до C++98 (когда Borland фактически был референсной реализацией шаблонов).

Кстати, с Си было то же самое - спека делалась по распространенным компиляторам, прежде всего pcc.

tailgunner ★★★★★
()
Последнее исправление: tailgunner (всего исправлений: 2)
Ответ на: комментарий от MyTrooName

Это то сарказм, но вот в реальности действительно нет смысла во временных переменных.

fn read_file_contents(path: &str) -> Result<String> {
    let mut file = File::open(path)?;
    let mut contents = Vec::new(); 
    file.read_to_end(&mut contents);
    let contents = String::from_utf8(contents)?;
    let contents = contents.trim();
    contents
}


fn read_file_contents(path: &str) -> Result<String> {
    let mut file = File::open(path)?;
    let mut contents_bytes = Vec::new(); 
    file.read_to_end(&mut contents);
    let contents_string = String::from_utf8(contents)?;
    let contents_trimmed = contents.trim();
    contents_trimmed
}

(да, я знаю что в stdlib есть другие методы, да, я знаю что можно написать проще, но суть отражает)

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

reference != specification #2

Я бы спросил, где именно у меня ты нашел утверждение «reference == specification» и чем ситуация с Rust отличается от ситуации с Си и Си++, но очевидно, что ничего разумного ты не скажешь.

tailgunner ★★★★★
()
Последнее исправление: tailgunner (всего исправлений: 3)
Ответ на: комментарий от tailgunner

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

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

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

...в том числе родственников, ага.

Чушь не пори. Спеку может написать кто угодно. Даже стандарт может написать кто угодно.

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

Страуструп

Страустрап

По-русски, правильнее будет «Страуструп».

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

Спеку может написать кто угодно. Даже стандарт может написать кто угодно.

приехали..

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

Ты спеку C++ видел-то хоть раз? или тебе нищета не позволяет скачать её с сайта ISO?

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

Спеку может написать кто угодно. Даже стандарт может написать кто угодно.

приехали..

Ты не знал? Теперь ты знаешь. А еще ты, наверное, не знал, что довольно долго спекой Си была K&R. А для C++ - The C++ PL Страуструпа.

стандартизация - это группа серьёзных товарищей, которая собирается специально для проверки спеки, выверки всех доводов, аспектов, проверки контрольных подсчётов, доказательств

Какая незамутненность.

Ты спеку C++ видел-то хоть раз? или тебе нищета не позволяет скачать её с сайта ISO?

Видел, не переживай. А еще я помню времена, когда не было ни спеки ISO, ни стандарта, а разные компиляторы уже были. Потому что была The C++ PL - неофициальная спека, которая «гнулась под реализацию».

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

ну извини.. под словом «спека» у меня подразумевается международный нерушимый стандарт, на который все должны дрочить и облизывать, а не что-то что гнётся при первом порыве вагинальных газов.. у меня всё.. у нас с тобой разные спеки и стандарты.

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

Тем, что bash,sh,zsh,etc. это языки командной строки.
И если ты пишешь my_cool_prog param1 param2, то ты передаёшь в программу строки «param1» и «param2», а не значения переменных param1 и param2.
Так исторически сложилось. Так удобнее большинству кто работает в командной строке.
Можно конечно написать свой шелл с БДиШ, где задавать строки только через «» или ", но кому он нафиг сдался будет?

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

под словом «спека» у меня подразумевается международный нерушимый стандарт, на который все должны дрочить и облизывать

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

tailgunner ★★★★★
()
Последнее исправление: tailgunner (всего исправлений: 2)
Ответ на: комментарий от anonymous

Хех. Некоторые производители мониторов облизывают стандарт DisplayPort, и приходится пользоваться кабелем HDMI. А у некоторых есть здравый смысл, и они кладут на требование передавать компьютеру сообщение об отключении монитора при переходе монитора в режим сна. А не дожидаются пока комиссия спеку поменяет.

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

а что плохого в «требование передавать компьютеру сообщение об отключении монитора при переходе монитора в режим сна»?

anonymous
()
Ответ на: комментарий от mersinvald
use serde_json::*;

fn get_port(path: &Path) -> u64 {
    let json = from_str::<Value>(&fs::read_to_string(path).unwrap()).unwrap();
    json["server"]["port"].as_u64().unwrap()
}

fn get_port2(path: &Path) -> u64 {
    from_str::<Value>(&fs::read_to_string(path).unwrap()).unwrap()
        ["server"]["port"].as_u64().unwrap()
}

лично я за первый вариант из двух

MyTrooName ★★★★★
()
Последнее исправление: MyTrooName (всего исправлений: 2)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.