LINUX.ORG.RU

Rust 1.22 (и Rust 1.22.1)

 


1

8

Почему сразу две версии? Чтобы задницы злопыхателей и критиков частых релизов полыхали ещё сильнее! (Как вариант, потому что 1.22.1 содержит патч, устраняющий баг в релизе 1.22, проявляющийся в Cargo у пользователей ОС macOS High Sierra, но это неточно.)

Что нового?

  • Основная фича: теперь вы можете использовать ? с Option<T>:
    fn try_option_some() -> Option<u8> {
        let val = Some(1)?;
        Some(val)
    }
    assert_eq!(try_option_some(), Some(1));
    
    fn try_option_none() -> Option<u8> {
        let val = None?;
        Some(val)
    }
    assert_eq!(try_option_none(), None);
    

    Пока функциональность ограничена; так, вы не можете писать код, который смешивает Result'ы и Option'ы в одной и той же функции, к примеру. Это станет возможным в прекрасном далёко.

  • Типы, реализующие Drop теперь доступны в `const` и `static` определениях:
    struct Foo {
        a: u32,
    }
    
    impl Drop for Foo {
        fn drop(&mut self) {}
    }
    
    const F: Foo = Foo { a: 0 };
    static S: Foo = Foo { a: 0 };
    

    Ничего особенного, но, согласитесь, приятно.

  • Два последних изменения в компиляторе должны ускорить компиляцию в режиме отладки.
  • T op= &T теперь работает для примитивных типов:
    let mut x = 2;
    let y = &8;
    
    // это не работало ранее, но теперь работает
    x += y;
    

    А раньше бы пришлось использовать разыменование: x += *y.

  • Улучшенные бэктрейсы на macOS.
  • Теперь вы можете создавать `compile-fail` тесты в Rustdoc:
    /// ```compile_fail
    /// let x = 5;
    /// x += 2; // shouldn't compile!
    /// ```
    
  • Наконец, мы удалили `le32-unknown-nacl` из поддерживаемых целей сборки. Google отказался от PNaCl в пользу WebAssembly. Вы уже можете компилировать Rust код в WebAssembly.

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

Стабилизация stdlib

Несколько новых API было стабилизировано в этом выпуске:

Cargo

★★★★★

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

Смотрю на новости по Rust, смотрю. И с каждой новостью всё меньше желания учить этот инопланетный язык.

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

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

Что характерно, после очень хорошего релиза C++11 и неплохого C++14 комитетчики плюсцов тоже тронулись умом на волне фичедрочерства.

dzidzitop ★★
()

теперь вы можете использовать ? с Option<T>:

нужно. кто знает, почему это сразу не запилили, вместе с Result?

вы не можете писать код, который смешивает Result'ы и Option'ы в одной и той же функции, к примеру. Это станет возможным в прекрасном далёко

а это как?

T op= &T теперь работает для примитивных типов

А раньше бы пришлось использовать разыменование: x += *y.

и это было прекрасное время. чем им явное разыменование помешало?

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

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

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

Хочешь улыбнуться? Хочу получше разобраться с Cargo на практике. Мне Cargo понравился, не Rust.

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

теперь вы можете использовать ? с Option<T>:

нужно. кто знает, почему это сразу не запилили, вместе с Result?

В оригинале:

The headline feature for this release is one many have been anticipating for a long time: you can now use ? with Option<T>! About a year ago, in Rust 1.13, we introduced the ? operator for working with Result<T, E>. Ever since then, there’s been discussion about how far ? should go: should it stay only for results? Should it be user-extensible? Should it be usable with Option<T>?

вы не можете писать код, который смешивает Result'ы и Option'ы в одной и той же функции, к примеру. Это станет возможным в прекрасном далёко

а это как?

Лениво искать подробности. Вот обсуждение этого PR.

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

Если ты хочешь использовать Карго, тебе не обязательно изучать Раст. Крнфиг пишется не на Расте.

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

О да, vox populi. Что глас народа даёт в пределе, хорошо описал С. Михалков в басне «Слон-живописец». И раст на всех парах туда приближается.

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

чем им явное разыменование помешало?

Конкретно в этом случае он не особо что-то значит и обратно: отсутствие разыменования никак не сказывается на работе с памятью в этом конкретном случае: AddAssign принимает ссылку как rvalue.

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

Вот только применение его ограничено растом пока что. А писать конфиги для Cargo, не используя под какой-либо проект - онанизм какой-то.

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

Куча непонятных побрякушек и полный маразм сознания

Фигня. Вот цепочки из типов-трейтов, которые часто встречаются в парсерах или tokio, вот это жесть. Как выведет тебе тип из 20 вложенных трейтов, сиди вспоминай как с плюсах хорошо было

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

Как выведет тебе тип из 20 вложенных трейтов, сиди вспоминай как с плюсах хорошо было

В самых старых плюсах до появления шаблонов?

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

Конкретно в этом случае он не особо что-то значит и обратно: отсутствие разыменования никак не сказывается на работе с памятью в этом конкретном случае: AddAssign принимает ссылку как rvalue.

звучит как ненужно. как я понял, это только для абстрагирования от конкретного типа выражения (ссылка/value), но я питонщик, у нас «Explicit is better than implicit»

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

Ага, намного лучше в плюсах

Ну вообще-то в плюсах этот код должен выглядеть так:

#include<algorithm>
#include<array>
using namespace std;
 
int main(){
    array a { 0, 1, 1 };
 
    if(any_of(a.begin(), a.end(), [](double d) { return d <= 0; }))
        throw invalid_argument("Geometry with bin width less or equal to zero");
}

https://godbolt.org/g/SYTrM1

А когда подвезут ranges (они пока experimental в TS, но есть уже реализации), то будет так:

#include<array>
#include<ranges/algorithm>
using namespace std;
 
int main(){
    array a { 0, 1, 1 };
 
    if(any_of(a, [](double d) { return d <= 0; }))
        throw invalid_argument("Geometry with bin width less or equal to zero");
}
anonymous
()
Ответ на: комментарий от MyTrooName

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

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

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

Эти ranges нужны, чтобы не указывать начало и конец массива явно?

Не только, там еще дополнительные типы, функции и пр. Например:

size_t h = accumulate(a | view::transform(hash) | view::take(10), 0);
anonymous
()
Ответ на: комментарий от dzidzitop

Ты в каждый тред про раст приходишь поныть какой раст плохой и неправильный. Аргументы по существу то будут?

То, что тебе не нравится синтаксис — это не по существу, удобство синтаксиса — вопрос привычки. Сахара в расте достаточно для комфортного кодинга.

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

if(any_of(a.begin(), a.end(), [](double d) { return d <= 0; }))

Если Лисп называли «овсяной кашей с обрезками ногтей», то как назвать это? «Овсяная каша с обрезками ногтей и выбитыми зубами»?

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

1) &8
2) в чём смысл писать let вместо типа
3) кто придумал это let? это от let's party tonight?
4) что за бред что это раньше не работало: «x += y;» и в чём причина что этот код может в принципе не работать.
5) в чём смысл обработки ошибок через Result. Все ошибки любой природы смешать в кучу?

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

хз. этот код читается без напряга - «если есть хоть один элемент в диапазоне от a.begin() до a.end() который <= 0, то выполни этот if».

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

Ты это сейчас всерьез или в рамках традиционной для растосрачах манеры ведения дискуссий (т.е. троллинга)?

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

1) &8

Адрес константы 8, очевидно

2) в чём смысл писать let вместо типа

В выводе типов. Тебя не возмущают var в Java и auto в Си++ или возмущают тоже?

3) кто придумал это let?

Думаю, какой-то математик. В Rust это пришло из Ocaml.

это от let's party tonight?

Нет.

4) что за бред что это раньше не работало: «x += y;» и в чём причина что этот код может в принципе не работать.

Назови источник бреда, если не являешься им сам.

5) в чём смысл обработки ошибок через Result.

В удобстве и упрощении рантайма.

Все ошибки любой природы смешать в кучу?

Природа ошибки описывается, внезапно, типом. Как и всё остальное.

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

хз. этот код читается без напряга - «если есть хоть один элемент в диапазоне от a.begin() до a.end() который <= 0, то выполни этот if».

Я знаю, что значит этот код. Но лишь потому, что я программирую на Си++. А претензии к синтаксису Rust предъявляют те, кто на нем не программируют.

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

1) &8

Согласен, явное лучше.

2) в чём смысл писать let вместо типа

Тип писать не нужно.

3) кто придумал это let?

То ли Robin Milner, то ли Peter J. Landin.

что за бред что это раньше не работало: «x += y;»

Ты хочешь сложить T и &T?

quantum-troll ★★★★★
()
Ответ на: комментарий от eao197

Я вполне серьезно сказал, что синтаксис приведенного фрагмента уродлив. Похоже, вид уродства я тоже описал удачно.

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

Я вполне серьезно сказал, что синтаксис приведенного фрагмента уродлив.

Как этот фрагмент ты бы лично переписал в не уродливом синтаксисе?

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

Адрес константы 8

гениально.

а потом константа числа 8, которая в этом языке имеет адрес, складывается с переменной, содержащей 2.

если переписать с типами, то будет очевиднее.

const int x = 2;
int *y = &8; // будем считать что это скомпилируется.
y += x;

ну бред же.


Назови источник бреда, если не являешься им сам.

у топикстартера это явно написано.

// это не работало ранее, но теперь работает
x += y;


ошибки не описываются каким-то одним на всех типом, внезапно. А если типы разные, то возникают проблемы ABI.

dzidzitop ★★
()
Ответ на: комментарий от quantum-troll

Ты хочешь сложить T и &T?

процитировал выше топикстартера.

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

Если Лисп называли «овсяной кашей с обрезками ногтей», то как назвать это? «Овсяная каша с обрезками ногтей и выбитыми зубами»?

А никто и не говорит, что это выглядит хорошо и не надо улучшать. Например, если будет принято всего два рассматриваемых предложения, то код будет выглядеть так:

if(a.any_of($0 < 0))

И то, что в Rust идут к пути упрощения, я только приветствую.

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

Аргумент простой - это что за бред?

let mut x = 2;
let y = &8;

Если этот учебный пример переписать по-другому, тебе станет легче?:

let mut x = 2;
let y = 8;
...
let z = &'a y;

Virtuos86 ★★★★★
() автор топика

Руст не нужен.

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

Как этот фрагмент ты бы лично переписал в не уродливом синтаксисе?

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

any_of(a.begin(), a.end(), lambda d: d <= 0)
с типом d должен разбираться вывод типов,

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

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

1) &8

Взятие ссылки на 8

в чём смысл писать let вместо типа

Локальный вывод типов. Зачем в C++ auto?

кто придумал это let? это от let's party tonight?

Без комментариев

что за бред что это раньше не работало: «x += y;» и в чём причина что этот код может в принципе не работать.

Внезапно несоответствие типов. Так бывает в статически-типизированных языках.

в чём смысл обработки ошибок через Result. Все ошибки любой природы смешать в кучу?

В чем смысл обработки ошибок через исключения? Все ошибки любой природы смешать в кучу?

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

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

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

any_of(a.begin(), a.end(), lambda d: d <= 0)

any_of(a.begin(), a.end(), [](auto d){ return d <= 0; })

Я так понимаю, что к уродству приводит только наличие []() и надобность в написании return?

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

ошибки не описываются каким-то одним на всех типом, внезапно

Описываются. Не описываются только в языках без AlgDT.

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

а потом константа числа 8, которая в этом языке имеет адрес, складывается с переменной, содержащей 2.

Тебе так только кажется. Это потому, что с языком ты не знаком совсем и об auto-dereferencing не знаешь.

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