LINUX.ORG.RU

Rust 1.19

 


3

8

Команда Rust рада объявить о последней версии Rust, 1.19.0. Rust это системный язык программирования, сфокусированный на безопасности, скорости и конкурентном выполнении.

Если у вас установлена предыдущая версия Rust, то получите Rust 1.19, выполнив команду:

$ rustup update stable

В противном случае, вы можете получить rustup с соответствующей страницы на нашем вебсайте и проверить детальные примечания к выпуску для 1.19.0 на Github.

Что нового в 1.19.0 stable

Rust 1.19.0 получил некоторые долгожданные возможности, но для начала примечание для наших пользователей Windows. На Windows Rust полагается на link.exe для линковки, который вы можете получить из “Microsoft Visual C++ Build Tools.” С последним выпуском Visual Studio 2017, структура каталогов для этих инструментов изменилась. Таким образом, чтобы использовать Rust, вы должны придерживаться инструментов 2015 или использовать обходной путь (такой как запуск vcvars.bat). В 1.19.0 rustc теперь знает, как найти инструменты 2017, и они работают без использования обходных путей.

А теперь к новым возможностям! Rust 1.19.0 это первый выпуск, который поддерживает объединения (unions):

union MyUnion {
    f1: u32,
    f2: f32,
}

Объединения это вид перечислений (enums), но в отличие от последних они «непомечены» («untagged»). Перечисления имеют «пометку», которая хранит информацию, какой вариант является правильным в рантайме; объединения игнорируют эту пометку.

Так как мы можем интерпретировать данные, хранящиеся в объединении, используя неправильный вариант, и Rust не может проверить это для нас, это означает, что чтение или запись поля объединения является unsafe:

let u = MyUnion { f1: 1 };

unsafe { u.f1 = 5 };

let value = unsafe { u.f1 };

Сопоставление с образцом также работает:

fn f(u: MyUnion) {
    unsafe {
        match u {
            MyUnion { f1: 10 } => { println!("ten"); }
            MyUnion { f2 } => { println!("{}", f2); }
        }
    }
}

Когда полезны объединения? Одним из основных случаев использования является интероперабельность с Си. C API могут использовать объединения, и во многих областях часто это делают, и с появлением объединений в Rust написание оберток для API подобных библиотек становится значительно проще. Дополнительно, из этого же RFC:

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

Эту возможность уже давно ждали, и еще больше улучшений на подходе. Сейчас объединения могут только содержать Copy типы и не могут реализовывать Drop. Мы ожидаем снятия этих ограничений в будущем.

Также циклы loop теперь имеют возможность возвращать значение при выходе с break:

// old code
let x;

loop {
    x = 7;
    break;
}

// new code
let x = loop { break 7; };

Rust традиционно позиционируется как «язык, ориентированный на выражения», в котором большинство вещей являются выражениями, вычисляющимися в значения, а не директивами. Раньше loop странно выделялся, так как был директивой.

Что насчет других форм циклов? Здесь еще не всё ясно. Посмотрите этот RFC для ознакомления с некоторыми дискуссиями вокруг открытых вопросов.

Замыкания, которые не захватывают окружение, теперь могут быть приведены к указателю на функцию:

let f: fn(i32) -> i32 = |x| x + 1;


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

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

Наибольшей новой библиотечной возможностью являются макросы eprint! и eprintln!. Они работают так же, как и print! и println!, но пишут в стандартный поток ошибок, а не в стандартный поток вывода.

Другие нововведения:

.

И некоторые недавно стабилизированные API:

Смотрите детальные примечания к выпуску для получения более подробной информации.

Cargo

Cargo в основном получил небольшие, но значимые улучшения в данном выпуске. Так, Cargo больше не проверяет локальный рабочий каталог для индекса crates.io. Это должно обеспечить меньший размер файла для реестра и улучшить время клонирования, особенно на машинах Windows.

Другие улучшения:

Смотрите детальные примечания к выпуску для получения более подробной информации.

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

★★★★★

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

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

Пока все фанбои языков со своими «всеми манямирками» идут лесом

Ну я хз, видимо ты живешь в какой-то своей вселенной.

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

только выродок какой-то мог такой синтакис придумать

Претензии к мудрецам сипипи. Зачем такое тащить в новый язык вопрос конечно интересный. Наверно, чтобы крестогеи чувствовали себя как дома.

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

Вообще я не понимаю всей этой мути: есть семафоры, есть мутексы, всё это базовые примитивы ОС.

Зачем в языке создавать какую-то супер-поддержку этим примитивам, при этом нагораживая бешенный огород высосанных из чужого носа абстракций, характерынх только для этого языка. Я не знаю, насколько это ускоряет написание кода, но по моему скромному мнению нужно делать сложные вещи более прозрачными и понятными, а не оборачивать их в 20 слоёв дополнительных абстракций ради лулзов и разбухания ЧСВ разработчиков.

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

Йой, бро, спокуха, это ж ты так и не назвал вообще ни одной вещи из перечисленных мной, которые ЕСТЬ в растоманском.

Да?! Это типа когда ты пишешь

Покажи пример синтаксиса функции Rust для дженериков и я тебе покажу, как можно было сделать то же самое по-человечески.

я тебе скидываю пример кода на Rust, а ты переписываешь его на C# (или что-это?!) и добавляешь отсебятины и такой типа

И где здесь вложенность угловых скобок?

Каких скобок!? Хрен знает от куда это у тебя там в голове возникло, но я отвечаю на это

А это уже, видимо, я пропустил. Можете скинуть пример?

- С вашей стороны игнор или слив? Что это?

Ни операторов типа With

Разупорись, я тебе уже ответил, твой with делается в Rust без With, или тебе принципиально наличие лишнего вводного слова при аналогичном функционале?

ни дженериков

Тот пример со структурой - это тоже дженерики, прикинь

ни самих типов данных, хоть немного интеллектуальнее дубовых uint'ов и прочего примитивного шита.

А ты же конечно спрашивал? Или мне телепатом быть?

Ну и пример слива =)

Начало слива

=> Rust 1.19 (комментарий)

<= Rust 1.19 (комментарий)

=> Rust 1.19 (комментарий)

<= Rust 1.19 (комментарий)

=> Rust 1.19 (комментарий)

Он пишет сначала

Пример, как Вы догадываетесь, гипотетический.

А затем пишет так

Я не собираюсь повторять какое-то говно. Я тебе не тупой болванчик-исполнитель.

Rust 1.19 (комментарий)

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

Ни операторов типа With, существенно сокращающих объём кода

Хоть один пример будет?

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

Когда я говорил и дерьмовом синтаксисе с мозгодробительными скобочками я имел в виду вот это (из педивикии) :

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

За «Rc<Cell<T>>» нужно просто убивать

Ключевое слово type позволяет объявить псевдоним для другого типа, можно примерно так:

type RCell<T> = Rc<Cell<T>>;

Поправьте меня, если косякнул с синтаксисом

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

Загуглил, таки да, это уже не тот басик который был в школе

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

Как можно не знать как выглядит C#

Эм, ну например, можно на нём не программировать и например, когда я учился он ещё не был популярен в РФ. Вопрос из разряда, как можно не отличить опкоды mips от avr

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

Тут если следить за сообщениями в теме уже станет очевидно про какой язык идёт речь. Для этого не нужны дополнительные знания

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

Превосходство лора(по сравнению с некоторыми формумами) в том что используя ссылку в самом начале можно быстро просмотреть ветвь рассуждений

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

Вот как это в Rust

let poi = Point { 
                    x: 10.237, 
                    y: -1.9,
                    tooltip = "WaterCloset here"
                };

А With вообще-то для другого. Он - для установки дефолтного контекста объекта:

With Object
  doSomething(.property, OtherObject.property)
  A=B+.someMethod(par0,par1,parN)
End With

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

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

Ну извините уж, я тут ещё, по мимо срачей, работать пытаюсь и все сообщения читать не успеваю

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

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

В смысле тыкать на «Ответ на: комментарий».

Таки если человек говорил с другим человеком, то это кнопка не особо поможет.

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

А With вообще-то для другого

Ну тут таки да, такого нет.

ровно по той же самой причине

Понятно

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

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

Это черезвычайно похоже на костыль, когда кодить приходится на телефоне(кнопочном, без qwerty раскладки). Автодополнение прекрасно разрешает подобную задачу. Кроме того, если метод объекта возвращаетс this(или что там в каждом конкретном случае), то цепочку вызова методов можно компоновать.

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

А With вообще-то для другого

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

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

Мне не нравится такой синтакис:

object.in.long.hierarchy.A=1
object.in.long.hierarchy.B=1
object.in.long.hierarchy.C=1
...ещё 1e+4 упоминаний "object.in.long.hierarchy."

Это создаёт ощущение «объёмного» кода и заставляет читать какой-то мусор 10000 раз.

ИМХО куда удобнее делать, например, так:

with object.in.long.hierarchy
   (.A,.B,.C)=(1,1,1)
end with

Коль скоро With придумали - значит, не только мне это показалось удобным.

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

Бро, вообще-то «with» отличная вещь. Ведет свою родословную из CL, емнип. Также есть в Питоне, где подобная сущность называется менеджер контекста, и можно создавать свои собственные, помимо встроенного with. Я думаю, для внедрения этой функции достаточно написать процедурный макрос, возможностей обычного не хватит.

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

Это черезвычайно похоже на костыль, когда кодить приходится на телефоне

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

вот, зацени последний пример http://www.freebasic.net/wiki/wikka.php?wakka=KeyPgWith

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

Мне кажется, что можно сделать так вместо With

Object
  .doSomething(.property, OtherObject.property)
  .map(...)

Но хз как map и подобные вещи работают

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

Это создаёт ощущение «объёмного» кода и заставляет читать какой-то мусор 10000 раз.

Решается элементарно

var t = object.in.long.hierarchy
t.A=1
t.B=1
Но рискну предположить что в недоязыках типа c++ или freebasic столь простой подход не сработает. Там нужны костыли.

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

не сработает

работает, конечно.

недоязыках

а это уже вброс на уровне нашего бейсико-фаната.

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

Мне кажется, что можно сделать так

Ну все, пошла спецолимпиада. Проще надо быть, а раст вас так и подталкивает к акробатике. Никаких проблем с записью a.b.c.d вообще нет. Если таких строк 100500 подряд, тут с алгоритмом какая то жопа, или не хватает выразительности языку.

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

Не ну вы не поняли, в Rust есть возможность юзать что-то вроде функционального программирования, но я в этом не разбираюсь, т.к. не нужно. Сделал предположение, что можно вместо with заюзать функциональный подход

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

Можно, и иногда нужно. Например, для реализации транзакционной семантики. А кувыркаться просто потому что x.y.z некрасиво и повторяется, не нужно. With в питоне, насколько я помню, запилили из-за отсутствия многострочных лямбд. Т.е. языку тупо не хватает выразительных средств, и потому сделали костыль для частного случая. Бейсик-стайл.

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

Решается элементарно

Это не решение. Это создание лексического мусора в виде дополнительной переменной. Зачем? А если нужно так сделать 20 раз в одном блоке кода? Давай тогда назовём переменную with ;)

А потом искать по всему коду, где это t создалось и что ещё за f*ng такой с обфусцированным именем.

Блоки with...end with чётко выделяют область действия контекста. Другое дело, что контекст устанавливается только для одного объекта, но чаще всего этого достаточно. Мало того, это диспилинирует, мотивируя не писать винергетокод, а все действия, логически связанные с тем или иным объектом, группировать в блок with.

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

И в чём трудность понимания последнего примера по сравнению с ZYX<'a<C<T>>>, которые так любят растоманы?

По-моему очевидно: установили контекст первого объекта-прямоугольника, присвоили значения, установили контекст другого - присвоили значения. Границы блока действия "." перед литералом элементарно устанавливаются в любой IDE, да и без неё чаще всего тоже (блоки with обычно небольшие).

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

ОК, и как предлагаете выходить из ситуации, когда есть таки объект или переменная a.b.c.d и нужно всячески активно оперировать ею? Передать в функцию, чтобы оно там стало this? Кстати, вы слышали о том, что вызов функции - довольно небесплатная вещь в любом языке?

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

Передать в функцию, чтобы оно там стало this? Кстати, вы слышали о том, что вызов функции - довольно небесплатная вещь в любом языке?

Я слышал, что в современных компиляторах есть inline и LTO.

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

по сравнению с ZYX<'a<C<T>>>

Это не раст. В расте будет ZYX<'a, C<T>>. И ничего раст-специфичного тут нет, не считая лайфтайма. Обычный шаблонный код. В C++/D/Java будет так же.

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

Ты сначала пойди и прочитай, что это такое. Я не силен в C++, но скорее всего менеджер контекста пересекается по назначению с RAII.

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

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

Плохо помнишь, RTFM.

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

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

По строчкам кода это не дороже твоего решения. Что у программиста, что у компилятора память не закончится от +1 переменной.

А потом искать по всему коду, где это t создалось и что ещё за f*ng такой с обфусцированным именем.

А как сказать что это за with? В IDE есть такая фича: перейти к определению. Если в блокноте её нет, то это проблема пользователей блокнота. И потом, хорошо когда функция влазит на экран целиком. Если у тебя функции не влезают на экран, то это только твои проблемы.

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

Как правило это нужно только при инициализации. А тебе уже приводили комактный вариант

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

Кстати, вы слышали о том, что вызов функции - довольно небесплатная вещь в любом языке?

Времена 8битных устройств прошли.

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

скорее всего менеджер контекста пересекается по назначению с RAII

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

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

вызов функции - довольно небесплатная вещь

Ладно, не буду вызывать, напишу x.y.z 3 раза, рука не отвалится. Но вообще то я не против, пусть будет этот сахарок. Только в раст не надо тащить, там и так уже напластования ого-го. Смешались в кучу кони, люди. Уже и не поймешь какого уровня язык и для чего.

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

Шо, опять объяснять?
Не понял, про какие лямбды идет речь, как и этот пассаж:

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

Википедия описывает RAII так.
Юзкейс для with как менеджера контекста иллюстрирует типовой пример:

f = open("file")
try:
    # выполняем какие-то манипуляции с открытым файлом
    …
finally:
    # ветка `finally` гарантированно выполняется, и мы гарантированно закрываем файл
    f.close()
Это идиоматичный код: захватываем ресурс, работаем с ним и гарантированно освобождаем его, исключая порчу данных. Но это тупой код (в ветке `finally` механическое набивание освобождения ресурса), и для этого используется констукция try/except/finally, чье прямое назначение всё-таки отлов исключений. Налицо необходимость в новой фиче, осенило ГВР, и он выдал на-гора не только with, но и механизм для создания собственных вундервафлей для работы с произвольными пользовательскими ресурсами с помощью этого with. И назвали этот механизм context manager.
Вышеприведенный пример, будучи переписан, выглядит так:
with f = open("file"):
    # выполняем какие-то манипуляции с открытым файлом
    …
Как только заканчивается блок with, файл будет автоматически закрыт. То есть здесь файл сам по себе выступает как менеджер контекста.
Понятное дело, под капотом всё та же кака с try/finally, но ее нужно писать только один раз — в самом менеджере контекста, а в остальном коде будет ляпота (осторожно, паста):
@contextmanager
def stdout_redirected(new_stdout):
    save_stdout = sys.stdout
    sys.stdout = new_stdout
    try:
        yield None
    finally:
        sys.stdout = save_stdout

with open(filename, "w") as f:
    with stdout_redirected(f):
        print "Hello world"
Открываем файл, перенаправляем в него стандартный поток вывода, печатаем в него «привет мир», возвращаем всё обратно, как было, закрываем файл. И всё это абсолютно в рамках exception safety. По-моему, очень классно.
Да, здесь нет «сахарку» из фри-бейсика, придется явно писать f.metod() и т.д.

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

Аналог на Ruby:

def with_stdout_redirected_to file
  original_stdout = $stdout.clone
  $stdout.reopen file
  yield
  $stdout.reopen original_stdout
end

File.open '/tmp/file', 'w' do |file|
  with_stdout_redirected_to file do
    puts 'this will be written to the file'
  end
  puts 'this will be written to stdout'
end

Было бы здорово, если бы в Python добавили поддержку многострочных лямб, чтобы можно было создавать DSL'и вроде teacup.

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