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)

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

Почему тогда во всех промышленных языках верблюд?

Потоиму что они все продвигались как объектно-ориентированные и косили под Smalltalk, которому мы и обязаны ублюдочным camelCase.

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

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

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

Я уверен, что вы лучше меня знаете, почему используют подчеркивания, а не пробелы.

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

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

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

Я делаю обычно так: fooBar<Tab>, и редактор в большинстве случаев дополняет без лишних вопросов. Опечатку дополнять не будет. Всп просто. А для локальных переменных и этого не надо, но у вас и там андерскоры понатыканы.

Выкинь свой Блокнот и используй нормальные редакторы: Саблайм Текст легко предлагает long_long_name, когда я ввожу lln. Какие андерскоры, о чем ты вообще??

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

в нормальных языках взятие адреса у целочисленного литерала - это ошибка компиляции.

Я бы не назвал нормальными языки, в которых разыменование неопределенного указателя - обычное явление.

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

А в смолтоке почему не змея? Тоже дураки?

А в смоллтоке так, потому что у машин, на которых смоллток разрабатывался, были убогие клавы без _.

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

А что, восьмерка не может в памяти храниться как обычные данные? Даже в «нормальных» языках

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

предлагает long_long_name, когда я ввожу lln

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

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

были убогие клавы без _

Будто нынешние клавы с _ в каком то анусе не убоги.

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

Литералы — это синтаксический сахар для примитивных типов, не более того. Ссылка на инстанс примитивного типа принципиально ничем не отличается от ссылок на инстансы сложных типов.

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

Зато ты достаточно упорот, чтобы доказывать превосходство одной конвенции именования идентификаторов над другой. Это примерно как доказывать, что имя «Вася» лучше имени «Петя».

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

Я так и не понял, почему ты хочешь запретить брать ссылки на константы? Какие преимущества даст этот запрет, может поможет словить какие-нибудь баги в коде? зачем вводить искусственные ограничения?

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

это не константа - это литерал.

можно начать с проблемы как определять оператор определения эквивалентности &8 и &8 (в том числе с учётом взаимодействия с C и unsafe кодом), а потом закончить внутренним представлением таких «объектов» и их временем жизни.

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

Множество нормальных языков не обязательно включает в себя C и C++ и тем более не ограничивается ими.

А ты вел речь об абстрактном языке в вакууме или о каком-то конкретном? Если о конкретном - назови его. Я не могу припомнить языка в котором есть операция «взять адрес» и нет возможности разыменовать некорректный указатель.

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

Работать с литералом как с переменной нельзя не только в C и C++.

Но в компании с rust есть жаваскрипт и прочий C#, где 8 является объектом.

dzidzitop ★★
()
Ответ на: комментарий от dzidzitop
struct Foo {
  int x;
};

В чем по твоему заключается принципиальная разница между 8 и Foo{.x = 8} ?

Почему 8 это литерал, а Foo{.x = 8} это уже объект? Почему восьмерка не может быть обьектом? зачем вводить отдельную сущность для интов?

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

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

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

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

То есть ты так и назовешь «нормальный язык», о котором ты говорил. Ну окей, чо.

Принципиальная разница между 8 и переменной заключается в том, что 8 не занимает память, а переменная занимает

Какие глупости. И переменная может не занимать память (слыхал про оптимизацию?), и литерал может занимать.

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

Я говорил о литералах, а не о «нормальных языках где есть разыменовывание указателей».

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

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

Литерал - это часть синтаксиса языка. Но ты, вероятно, путаешь временную переменную и литералы.

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

Я говорил о литералах, а не о «нормальных языках

dzidzitop> в нормальных языках взятие адреса у целочисленного литерала - это ошибка компиляции.

Назови наконец этот нормальный язык.

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

Работать с литералом как с переменной нельзя не только в C и C++.

В Rust всё есть выражение. let — не область памяти, а привязка к результату выражения. 8 — выражение, от которого берётся ссылка. Вот для примера, может тебе станет чуть более понятно.

let c = ...; // вычисляем какое-то условие
let x = & if c { 8 } else { 0 }; // берём ссылку на результат выражения if-else

Ссылка — не указатель, она может ссылать на регистр, на стек, на .data, на .bss или на .rodata.

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

Ссылка от выражения - это что-то сферическое в вакууме. И нафиг такие воображаемые «ссылки», не имеющие отображения в железо, не нужны. Разве что это ссылка может означать для компилятора ленивые вычисления. Но для rust это точно не так.

Или ты знаешь хороший пример, где иметь ссылку на 8 жизненно необходимо, и без ссылки на 8 никак не обойтись?

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

Этот анонимус - некачественный. Нет в расте никаких ссылок на регистры. Будет ссылка на временное значение на стеке.

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

на плюсах для

void f(int &);

f(6);


тоже будет создана временная переменная на стэке со значением 6, если не оптимизируется компилятором в подстановку значения вместо переменной. А если внутри f будет &x, то будет браться адрес переменной, а не литерала. Ну если операция взятия адреса не выкинется за ненадобностью, то переменная будет создана на стэке всегда.

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

Любой язык, который не C/С++ - ненормальный.

поправил

А других аргументов, кроме ненормальности у тебя есть? и вообще, кто определяет что нормально а что нет?

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

Любой язык, в котором литерал имеет адрес - ненормальный.

Раньше ты говорил о нормальных языках, теперь - о ненормальных.

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

Языки C и C++ тоже не очень, так что поправка не соответствует тому, что я написал.
И есть ещё, минимум, Pascal, который тоже не позволит взять адрес целочисленного литерала.

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

Нет.

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

Это один из пунктов проверочного списка во время сдачи языка страждущим программистам.

Почему? Потому что появляется вопрос времени жизни (включая вызов деструкторов/финализаторов у «полноценных объектов»), эквивалентности ссылок на один и тот же литерал в разных единицах трансляции, проблема приведения типов, включая const_cast и прочее.

Поэтому rust пускай позволяет иметь ссылку на 8.

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

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

Часть синтаксиса языка - это продукция его грамматики. Взять ее адрес не позволяет вообще никакой язык.

Это один из пунктов проверочного списка во время сдачи языка страждущим программистам.

Не считай себя программистами (и неважно, сколько там у тебя личностей или глистов).

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

Замечательно. И чем это отличается от раста? `&8` означает, что где-то (в данном случае в .rodata) будет зарезервировано место для хранения значения литерала и будет взят адрес этого места.

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

`&8` означает, что где-то (в данном случае в .rodata) будет зарезервировано место для хранения значения литерала и будет взят адрес этого места.

И даже этого может не произойти.

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

восьмерка не может в памяти храниться как обычные данные?

Восьмёрка - не может

Наверно, лучше продолжить этот разговор после выходных.

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

Естественно. Подразумевается: «в случае, если всё это не будет оптимизировано при кодогенерации».

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

Кстати, как у нормальных языков со взятием указателей на строковые литералы?

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

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

А C99 считается нормальным языком или нет?

#include <stdio.h>

int main()
{
	const int *int_ptr = &(int){8};
	printf("Test %i\n", *int_ptr);
	return 0;
}

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

это не константа - это литерал.

Батенька, всё в кучу. Литерал — синтаксическая сущность, константа — семантическая.

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