LINUX.ORG.RU

Альфа-версия Rust 1.0

 


2

6

9 января тихо и незаметно вышла альфа-версия Rust 1.0. Этот релиз является этапным в том смысле, что набор возможностей языка зафиксирован и в версиях 1.x значительных несовместимых изменений больше не будет (см. ниже); то же относится и к стандартной библиотеке. Гарантии стабильности означают, что Rust уже можно изучать, не опасаясь скорого устаревания полученных знаний из-за эволюции языка.

Тем не менее, апгрейд в линии от альфа-версии до финальной версии может вызвать мелкие несовместимости (Sync/Send changes, переименование uint/int в usize/isize), но все проблемы планируется решить до выпуска 1.0.

Основные изменения со времени предыдущего релиза:

  • улучшенная поддержка массивов и подобных им контейнеров в языке: DST
  • унификация трейтов и замыканий в виде unboxed closures: теперь замыкания - это просто объекты, реализующие определенные трейты

Полный список изменений с подробным их описанием по ссылке:

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

★★★★★

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

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

Тогда у него и стандартная библиотека будет, как сишная. Нет уж, спасибо.

С х%я ли? Зачем линковщику впихивать в бинарник больше данных при наличии в стандартной библиотеке большего набора возможностей?

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

есть unsafe и им будут пользоватся

Это так себе аргумент. Ансейф есть почти везде. В Go, кстати, тоже что-то такое наблюдается. Впрочем, я не специалист в языке, но разве оно не позволяет «выстрелить себе в ногу» в классическом смысле?

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

После С++ так вообще всё замечательно.

Хрен редьки не слаще:

let n = std::os::args().get(1).and_then(|n| n.parse()).unwrap_or(100);
anonymous
()
Ответ на: комментарий от Dicebot

невозможность использовать макрос вида println!«Hello» для простых строк,

В смысле? println!(«hello»); вполне работает.

D: auto i = to!uint(«5»);

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

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

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

Хрен редьки не слаще:

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

А пример синтетический.

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

А изобрази это на Си++

А ты думаешь в этом есть какие-то проблемы? На Си++ можно тоже «изобразить» namespace std::os::, тоже добавить такие функции или классы с методами. Но зачем через такую жопу решать такую простую и часто решаемую задачу?

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

А ты думаешь в этом есть какие-то проблемы?

Нет.

Но зачем через такую жопу решать такую простую и часто решаемую задачу?

Через какую «жопу»? Еще раз - изобрази решение на Си++ и сравни.

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

Я хочу выбросить скобки для вариантов с одним аргументом, как в D :)

Мне эта фичи никогда не нравилась. Однообразие - это неплохо, да и экономия копеечная.

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

Через какую «жопу»? Еще раз - изобрази решение на Си++ и сравни.

Если по сути забить на обработку ошибок (как в примере для rust):

argc > 1 ? stoi( argv[1] ) : 100

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

args(1).toInt() or 100
anonymous
()
Ответ на: комментарий от umren
rustc -D unsafe-blocks unsafe.rs 
unsafe.rs:3:20: 3:53 error: usage of an `unsafe` block [-D unsafe-blocks]
unsafe.rs:3     let u: usize = unsafe { std::mem::transmute(i) };
                               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: aborting due to previous error

Unsafe можно и запретить, а если кто-то будет использовать, то бить по рукам. :)

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

Если по сути забить на обработку ошибок (как в примере для rust):

Там нет забивания на ошибки.

argc > 1 ? stoi( argv[1] ) : 100

Код неэквивалентный - падает при кривом литерале.

И заметь, я не говорил в плюсах лучше

Ты сказал, что в Rust не лучше, чем в плюсах. Но в Rust лучше.

args(1).toInt() or 100

Монадку хочешь... нету монадок пока.

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

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

Какого аргумента? Если ты про тип переменной куда мы присваиваем, то можно. Если же про «тип в строке», то тоже можно, но другой функцией (parse).

Зачем вообще этот отвратительный синтаксис вида ::<>

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

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

Там нет забивания на ошибки.

Да ладно, вводим не число или большее кол-во аргументов - программе плевать.

Код неэквивалентный - падает при кривом литерале.

Не а, я специально взял stoi, он не падает, а кидает исключение про то, что параметр «кривой».

Ты сказал, что в Rust не лучше, чем в плюсах. Но в Rust лучше.

Окай... Ну ты хоть согласен, что можно и нужно сделать лучше?

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

С двумя match?

Меня вообще этот код смущает. Может он и «реальный» как утверждает анонимус, но я бы так не писал. Почему используется только второй параметр, где обработка остальных? Понятно, что можно найти примеры когда «так и надо», но зачем ровняться на граничные случаи?

Как-то так, в общем. Ну и для плюсов есть замечательная boost::program_option. Думаю, что на расте можно сделать, как минимум, не хуже.

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

Код неэквивалентный - падает при кривом литерале.

Не а, я специально взял stoi, он не падает, а кидает исключение про то, что параметр «кривой».

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

Ну ты хоть согласен, что можно и нужно сделать лучше?

Да. Но для этого нужно что-то вроде монад, а их решили не добавлять до 1.0. И даже то, что есть, уже короче и очевиднее Си++

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

Коду конвертера должно быть всё равно по большей части, это &str или String

Сейчас from_str не умеет работать сo String. Так что для строк «шума» будет ещё немного больше.

А str нужно чтобы показать, что работаем именно со строками, а не с любым типом. «Преобразовывать» любой тип может transmute, правда он делает несколько другое.

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

Меня вообще этот код смущает. Может он и «реальный» как утверждает анонимус, но я бы так не писал.

Мне тоже не сильно нравятся длинные шашлыки из методов, но... 4 - это еще терпимо. И это идиоматичный стиль Rust, кмк.

Как-то так, в общем

В три раза больше кода, а в чем выигрыш?

Ну и для плюсов есть замечательная boost::program_option

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

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

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

И программа выходит с сообщением об ошибке в stoi. Что гораздо лучше, чем выполняться дальше.

И даже то, что есть, уже короче и очевиднее Си++

let n = std::os::args().get(1).and_then(|n| n.parse()).unwrap_or(100);

vs 

int n = argc > 1 ? stoi( argv[1] ) : 100;

Окай.

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

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

Программа на Rust специально написана так, чтобы выполняться. Если бы твоя была написана так, она была бы в 3 раза длиннее.

Окай.

Твоя программа падает, программа на Rust работает. Такое вот окай.

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

Да. Но для этого нужно что-то вроде монад,

Вполне решаемо на плюсах:

or( args(1).to_int(), 100 )

Если args(1) или to_int() кидает исключение - возвращаем второй аргумент. Не хватает синтаксического сахара, но и так куда читабельнее и лучше чем в rust.

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

Хотя можно сделать лучше:

or( args[1], 100 )

Где or - шаблон, T выводится по второму параметру, а первый параметр кастуется к нему.

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

Вполне решаемо на плюсах:

or( args(1).to_int(), 100 )

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

И чисто из любопытства - значение какого типа возвращается args()?

Не хватает синтаксического сахара, но и так куда читабельнее и лучше чем в rust.

Только вот не работает.

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

но... 4 - это еще терпимо. И это идиоматичный стиль Rust, кмк.

Да без проблем. Но если оно уместно. Bезде и всегда такое делать в ущерб здравому смыслу просто «потому что идеоматический стиль» мне не кажется верным.

В три раза больше кода, а в чем выигрыш?

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

В Rust или Си++ - неважно.

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

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

Где or - шаблон

а точнее макрос, т.к. нужно еще сделать лямбду с try/catch

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

В три раза больше кода, а в чем выигрыш?

В расширяемости

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

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

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

Ок, повторю основную мысль: не верю, что такой (используем только второй параметр, остальное игнорируем) вообще нужен. Про то, что в С++ получается кода больше ты и сам знаешь.

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

не верю, что такой (используем только второй параметр, остальное игнорируем) вообще нужен

Да почему второй-то? args(0) - имя программы, args(1) - ее первый параметр, не?

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

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

я уже выше написал - лямбду «напишет» препроцессор

И чисто из любопытства - значение какого типа возвращается args()?

string ес-но, кастовать можно через lexical_cast, например

Только вот не работает.

#include <iostream>
#include <string>
using namespace std;

#define rust_useless(x, y) [](){ try { return x; }catch(...){}; return y; }()

int main()
{
   cout << rust_useless( stoi( "+++" ), 100 ) << '\n';
}

Можно еще добавить шаблон, как я писал.

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

Да почему второй-то?

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

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

я уже выше написал - лямбду «напишет» препроцессор

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

#define rust_useless(x, y) [](){ try { return x; }catch(...){}; return y; }()

Это уже больше, чем весь фрагмент кода на Rust.

И да, какой там тип возвращаемого значения args() на Си++?

tailgunner ★★★★★
() автор топика
Ответ на: комментарий от anonymous
std::os::args().get(1).and_then(|n| n.parse()).unwrap_or(100);

===

if (argc > 1) { // std::os::args().get(1)
    try {
        return stoi(argv[1]); // and_then(|n| n.parse())
    } catch(...) {
        return 100; // unwrap_or(100)
    }
} else {
    return 100; // unwrap_or(100)
}

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

Package unsafe contains operations that step around the type safety of Go programs.

так ты прочитай первую строчку, это совсем о другом

«Pointer therefore allows a program to defeat the type system and read and write arbitrary memory. It should be used with extreme care».

Не вижу особой разницы с Rust.

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

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

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

Это уже больше, чем весь фрагмент кода на Rust.

Макрос можно вынести в отдельную библиотеку. Вон в rust так же делают.

И да, какой там тип возвращаемого значения args() на Си++?

Если говорить про «ванильный» С++ - я уже привел пример более короткого кода чем на rust. Тебе он не понравился - это отдельная тема - что делать с неправильными параметрами. А в данный момент я описываю как на С++ можно сделать еще короче, если оформить это в виде отдельной библиотеки.

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

так ты прочитай первую строчку, это совсем о другом

Ну пусть так. Тем не менее, FFI для Gо ведь есть.

DarkEld3r ★★★★★
()
Ответ на: комментарий от numas13
if (argc > 1) { // std::os::args().get(1)
    try {
        return stoi(argv[1]); // and_then(|n| n.parse())
    } catch(...) {
        return 100; // unwrap_or(100)
    }
} else {
    return 100; // unwrap_or(100)
}

Да - на С++ тоже можно писать через жопу. Ни один ЯП тебе этого не запретит.

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

Макрос можно вынести в отдельную библиотеку. Вон в rust так же делают.

А в данный момент я описываю как на С++ можно сделать еще короче, если оформить это в виде отдельной библиотеки.

См. выше о boost::program_options

Если говорить про «ванильный» С++ - я уже привел пример более короткого кода чем на rust

Тебе уже несколько раз сказали, что код не эквивалентен коду на Rust.

программа rust не умеет сообщать, что параметр не число

А какой из твои вариантов умеет это?

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

это отдельная тема - что делать с неправильными параметрами.

Ну так сравнивать надо эквивалентный код. В коде на расте сознательно игнорируют любые ошибки. Идея мне не нравится, но твой код делает другое.

А в данный момент я описываю как на С++ можно сделать еще короче, если оформить это в виде отдельной библиотеки.

Сделать можно и на расте. Для такой простой задачи это не интересно.

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

программы ведь не эквивалентные.

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

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

Да - на С++ тоже можно писать через жопу.

Так в этом и суть.

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