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)

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

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

Именно поэтому программированию до сих пор учат на Паскале. И это правильно.

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

Ну это очевидно. Вот говорят, что язык безопасный и всё такое, так говнякать всё равно будут через unsafe.

Прикол в том, что при наличие бага, он будет в 99.[9]% в unsafe. А в C\C++ абсолютно в любом месте

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

Можно

Это в смысле возможно такое написать. Но делать так нельзя потому что это будет Undefined Behavior. По не мутабельной ссылке разрешается менять только то что лежит в UnsafeCell.

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

Кому надо? Я повторяю: дерево можно реализовать без unsafe.

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

Можно

Это в смысле возможно такое написать.

Да

Но делать так нельзя потому что это будет Undefined Behavior.

Спасибо за инфу. Я так-то вообще, стараюсь unsafe только для FFI использовать.

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

Сугубо ИМХО Паскаль избыточно многословен. Читается хорошо, тут не поспоришь, но зачем столько begin...end'ов этих - мне трудно понять. Впрочем, обесцененный синтаксис современных языкоподелок - куда хуже Pascal'я.

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

Так если так делать начнут, что половина кода будет в unsafe?

Ну нет уж)) Код с unsafe не проще писать, чем без unsafe. Так что народ тупо из лени будет следовать подсказкам компилятора в безопасном Rust, чем в unsafe ломать себе голову что там не работает и чего надо сделать, чтобы заработало

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

Мужик, ну ты чего!? Слился чтоли?!

Ты же писал =>

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

Я же тебе дал пример.

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

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

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

Ну, ленивые-то да, а всяким профи, что будет мешать делать жирные вставки? Получится короче, как с жабой. Типа не течёт, но иногда течёт.

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

Да же добавлю

struct Point<T> {
    x: T,
    y: T,
}

fn takes_anything<T>(z: T) {
  let int_origin = Point { x: z, y: z };
}

fn main() {
  takes_anything(0);
  takes_anything(0.0);
  takes_anything("Hello");
}

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

Получится короче, как с жабой.

Опять фантазируете?

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

Ну блин мужик, unsafe отличается от safe только этим

  • Разыменовывать сырые указатели
  • Вызывать unsafe функции (включая функции на Си, встроенные функции, сырое распределение)
  • Реализовывать unsafe типажи
  • Изменять статические переменные

    Состоит ли твоя программа на 50% из этого. Сомневаюсь. Но если тебе потребуется работать с сырыми указателями, то всё зависит от тебя. И если в unsafe ты будешь выделять память и херить на неё указатель, то это твои проблемы. Но без unsafe жить можно, я это гарантирую =)

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

И где здесь вложенность угловых скобок? Насколько я понимаю, таковая возникает при описании generic-прототипов функций (которые на деле разворачиваются самим компилятором в набор самых обычных не generic-функций).

В этом примере я бы написал так:

type Point: TDims is OneOf(int,float,double), \
            TLbl  is OneOf(label,ml_text)
  x is TDims
  y is TDims
  tooltip is TLbl
end type

poi is Point(float,label)

with poi
  .x=10.237
  .y=-1.9
  .tooltip='WaterCloset here'
end with
DRVTiny ★★★★★
()
Ответ на: комментарий от quantum-troll

Выражение:

a=1e+6

Оно же:

=(a,1e+6)

Я имел в виду, что a - это такое длииииинное целое. А компилятор почему-то решил, что это float. Вопрос: какого ***?

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

То, что ты не пишешь код в шестнадцатеричном редакторе - вкусовщина?

А само по себе существование over 9000 языков - это что, вкусовщина или нет? Да большинство из них отличаются друг от друга функционально и концептуально абсолютно минимально, с гулькин нос.

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

концептуально абсолютно минимально

То есть те же C, Haskell, Erlang и Python концептуально идентичные языки?

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

Без подсветки синтаксиса парсить нереально.

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

В общем очередной пример: я ничего не понимаю, но знаю как лучше.

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

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

Вообще-то я прямо специально привёл пример переноса строки. Не заметили?

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

Без подсветки синтаксиса парсить нереально.

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

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

1e+6 - это миллион. Просто миллион. Он целый, совершенно целый, в нём нет никакой дробной части.

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

Там не только пунктуации меньше, но и функционал пошире вообще-то. Во-первых, в качестве типа для x и y можно использовать только OneOf (один из) предопределённых в списке макро-определения времени компиляции. Во-вторых - есть ещё текстовое поле, тип которого тоже может варьироваться. Кстати, здесь же концепция интеллектуальной проверки аргумента: при попытке присваивания tooltip'у, заявленному как label, чего-либо, содержащего перевод строки - будет вызвано исключение либо времени компиляции, либо времени исполнения.

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

Какой там у нас Rust в 2017-м году умеет не присваивать переменной типа EMail нечто, что прямо по первому же символу не является EMail'ом? Ага, никакой не умеет. Зато мы делаем ракеты...

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

Теперь всё понятно - ты сумашедший

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

Не заметили?

Нет конечно. В нормальных языках для этого используется \n. А не костыль.

А так - да, писать в одну строку, желательно короткую строку.

Опыт питона показал обратное.

Выражения по смыслу - обычный человеческий язык.

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

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

Какой там у нас Rust в 2017-м году умеет не присваивать переменной типа EMail нечто, что прямо по первому же символу не является EMail'ом? Ага, никакой не умеет. Зато мы делаем ракеты...

И зачем это нужно системному языку. Но решается это так же, как и везде - валидацией.

Ну и алгоритм определения, что строка - email, по первому символу в студию.

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

Какой там у нас Rust в 2017-м году умеет не присваивать переменной типа EMail нечто, что прямо по первому же символу не является EMail'ом?

Red глянь. Недавно про него новость вот была. Там как раз есть тип e-mail, и как раз есть даже литералы этого типа, которые должны быть написаны как e-mail адрес.

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

Но решается это так же, как и везде - валидацией.

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

Ну и алгоритм определения, что строка - email, по первому символу в студию.

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

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

Он же начал создаваться как альтернатива плюсам когда они стагнировали? А зачем он сейчас, когда плюсы активно развиваются?

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

Я там отписался уже :) Собственно, я на Red запал раньше, чем на Julia, но у Red какие-то странные пристрастия к 32-м битам и View, злобно игнорирующий Linux. А так, ИМХО, хороший прототип языка будущего.

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

EMail'а или номера мобильного телефона

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

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

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

А можно какие-то критерии нормального языка от великого Гуру Нормальных Языков?

Ну вот строки чтоб можно было писать на три абзаца - это да, нужно. И читаемость очень повышает, и ЧСВ. А что ещё интересного предложите?

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

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

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

У библиотек же, как правило есть масса недостатков: начиная тем, что работают медленнее, нежели код в ядре языка (хотя бы потому, что библиотеки не обязаны создавать люди, идеально разбирающиеся во внутренней кухне компилятора) и заканчивая тем, что библиотека может неожиданно протухнуть, стать несовместимой, неподдерживаемой, а то и вообще платной.

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

Вспомнил как я под веществами сочинял:

Point T | (T * T * T): Add = {Point x * y | x: T, y: T}

Add LHS * RHS * Output | LHS, RHS, Output =
    {add {lhs * rhs | lhs: LHS, rhs: RHS} -> Output}

add: {Add LHS * RHS * Output | LHS = Point T,
                               RHS = Point T,
                               Output = Point T,
                               (T * T * T): Add} =
    add $ -> # |
        {lhs * rhs | lhs = {Point x * y | x = lx, y = ly},
                     rhs = {Point x * y | x = rx, y = ry}} = $,
        x = T.add {l * r | l = lx, r = rx},
        y = T.add {l * r | l = ly, r = ry},
        # = {Point x * y | x = x, y = y}

Здесь все наоборот, никаких ключевых слов нету.

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

чтобы эта валидация работала не только в рантайме

Наркоман? Откуда компилятору знать, что придёт в рантайме?

Спойлер: email уже 100 лет как не проверяют, ибо бесполезно. Нужно письмо на ящик отправлять и ждать подтверждения.

так почему бы этот действительно полезный функционал не делать частью самого языка?

Потому, что не наркоманы. А так - red lang.

речь шла не о том, что алгоритм должен по первому символу независимо от этого символа сразу что-то определять
прямо по первому же символу не является EMail'ом

У кого тут ещё тупняк?

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

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

Ты описываешь библиотеки Перла? С чего скомпилированная в машкод библиотека будет работать медленнее, нежели машкод, порожденный компилятором? Какая такая таинственная внутренняя кухня? Если предметная область требует знания внутренностей компилятора, а у вас их нет, то вы ничего и не напишете удовлетворительно работающего, а уж если либа протухла etc., то возникает вопрос о её нужности вообще.

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