LINUX.ORG.RU

Rust 1.9

 


0

3

Анонсирована очередная версия языка программирования Rust 1.9, разрабатываемого Mozilla совместно с сообществом. Примечательно то, что с момента релиза первого стабильного выпуска прошел 1 год.

Основные изменения:

  • Стабилизирован модуль std::panic, позволяющий перехватывать раскрутку стека. Соответствующие функции рекомендуется применять только в исключительных ситуациях, но никак не для эмуляции механизма try-catch.
  • Стабилизированы методы настройки TCP и UDP соединений; расширены возможности OsString, BTreeSet и HashSet; char может быть получен из UTF-16 последовательности; стабилизирована функция copy_from_slice(); появилась возможность работы с волатильными переменными с помощью read_volatile и write_volatile; сырые указатели обрели .as_ref() и .as_mut(), которые возвращают Option<&T>, где null будет представлен как None; в libcore для всех типов реализован Debug.
  • Разработчикам библиотек доступен атрибут #[deprecated], разрешающий компилятору слать предупреждения при использовании устаревшего API.
  • Специализация уже используется в ночном релизе и будет доступна в стабильном 1.11 через 3 месяца, но оптимизация .to_owned() и .to_string() таки попала в текущий стабильный выпуск.
  • Расширен список поддерживаемых платформ: mips-unknown-linux-musl, mipsel-unknown-linux-musl, i586-pc-windows-msvc.
  • Ускорено время компиляции монады с одинаковыми функциями.

Изменения в менеджере зависимостей Cargo:

  • В системе могут работать несколько cargo одновременно, блокировки теперь применяются на файлы.
  • Переменную окружения RUSTFLAGS можно использовать для передачи произвольных флагов компилятору.

Для кросс-компиляции подготовлен инструмент rustup, обеспечивающий тривиальное взаимодействие с каналами сборок компилятора (stable, beta, nightly), стандартными библиотеками и их документацией к различным операционным системам, а также обновление всего этого зоопарка одной командой.

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



Проверено: Falcon-peregrinus ()
Последнее исправление: shaiZaigh (всего исправлений: 2)
Ответ на: комментарий от eao197

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

Всё замечательно будет работать. Заменить лямбду на |accum, maybemq|accum.push(try!(maybemq))

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

Вот, например, неужели вы постоянно пишете new(nothrow)? Или вы никогда не делаете some_vector_with_strings.push_back(«another_value»)?

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

Исключения в new и push_back - это снова OOM. Который невозможен в 99% задач.

И много вашего кода в firefox, qt или llvm?

При чём тут это? Я не могу писать свои проекты в их стиле?

У gcc/clang есть классные флаги: -fno-rtti -fno-exceptions. И все становится прекрасно.

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

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

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

Исключения в new и push_back - это снова OOM.

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

Который невозможен в 99% задач.

Ну вот возьмем, скажем, Web-браузер, посредством которого мы сейчас с вами общаемся. У меня в браузере открыта куча вкладок и я открываю еще одну с «тяжелой» страничкой. При обработке содержимого этой страничке (на каком-нибудь тупом push_back-е) браузер сталкивается с OOM.

Мне, например, полный крах браузера ну совсем не понравится.

Я не могу писать свои проекты в их стиле?

Вы уж определитесь: крупные проекты вы пишете или свои. Складывается впечатление, что ваши проекты к числу крупных не относятся.

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

Т.е. вы всегда запрещаете исключения на уровне ключей компилятора? Что из стандартной библиотеки C++ вы тогда используете?

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

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

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

Как в этом случае будет выглядеть fold_result.

PS. За код спасибо!

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

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

Еще раз: google с их chrome, apple с llvm, и Qt Company с Qt - это пациенты и говнокодеры? Ну тут конечно диагноз.

Мне, например, полный крах браузера ну совсем не понравится.

Когда у меня кончается ОЗУ, а свопа у меня нет, то вся система стаёт колом. И половина приложений или зависает или завершается/убивается. Но ничего.

ваши проекты к числу крупных не относятся

Я и не претендовал на уровень корпораций. Десятки тысяч строк кода - не больше.

Что из стандартной библиотеки C++ вы тогда используете?

Ничего. Я ее не перевариваю. Мне достаточно Qt или -nodefaultlibs.

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

Ошибка так же является исключительной ситуацией.

Нет. Читай учебники.

Получил HTTP 500, брось исключение

Кхм. Долго объяснять, просто поверь на слово: то, что предусмотрено во время проектирования программы, не является ни ошибкой, ни исключительной ситуацией. Всё это штатные ситуации, предусмотренные логикой программы.

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

Как в этом случае будет выглядеть fold_result.

Как вариант:

loop {
    match p.next() {
        Ok(t) => {
            println!("{:?}", t);
        },
        Err(e) => {
            println!("{:?}", e);
            break;
        },
    }
}

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

Еще раз: google с их chrome, apple с llvm, и Qt Company с Qt - это пациенты и говнокодеры?

Интересно, откуда последовал такой вывод?

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

Отсюда вовсе не следует, что разработчики в Google или в Qt Company, которые _вынуждены_ отказаться от использования исключений по _историческим причинам_ находятся во власти этих иллюзий.

Но ничего.

Окай.

Ничего. Я ее не перевариваю. Мне достаточно Qt или -nodefaultlibs.

Давайте предположу. В Qt вы делаете что-то вроде:

QVector<QString> myVec;
myVec.push_back(QString("yet_another_value"));
А в случае ООМ просто тихо игнорируете все ошибки, до тех пор, пока не наткнетесь на нулевой указатель?

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

Ну я даже не представляю, как бы в Rust выглядели unchecked exceptions. Разве что внутри unsafe что-то наколдовать...

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

Ну а теперь сравните с C++ной реализацией accumutale, которая остается неизменной. Или с подобными реализациями в других языках с исключениями и поддержкой обобщенного программирования (каким-нибудь D или Scala).

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

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

Для этого нужно писать свой итератор, но этот итератор будет реализовывать тот-же контракт, что и итератор по массиву, а именно Iterator<Item=Result<MQ, MQError>>.

Поэтому код fold_result менять не придётся.

Вот, например, итератор по оконным сообщениям: https://github.com/red75prime/dxgen/blob/master/src/dxgen/scaffolding/src/win...

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

Пожалуйста: https://is.gd/NbhyAR

Этот самый .fold() аж в libcore добавили, неужели так необходимо городить свой велосипед?

fn main() {
    println!("{}", ["1", "abc", "2"].iter().filter_map(|s| s.parse::<i32>().ok()).fold(0, |sum, x| sum + x));
}
.parse() возвращает Result.

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

Поэтому код fold_result менять не придётся.

Что значит не придется? Там было: for item in iter в предположении, что ошибок быть не может. Теперь это не так. Сам item может получить ошибку. И как эта ошибка вернется из fold_result? Еще же никто не обрабатывает.

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

Еще же никто не обрабатывает.

Да. Нужно использовать код, который я писал выше.

Да, в этом случае исключения удобней. Но сама логика таких последовательностей не самая рядовая.

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

Что значит не придется? Там было: for item in iter в предположении

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

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

Исключения успешно игнорируются.

Йя-йя, натюрлих:

} QT_CATCH (...) {
     Data::deallocate(x);
     QT_RETHROW;
}

Прям во все поля игнорируются.

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

Точнее договорились, что Err(err) - это ошибка, Ок(err) - это нормальный результат. Макрос try!() это учитывает.

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

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

Ну, т.е., если говорить грубо, если в C++ мы знаем, что *it дает там T, и этот T пойдет в функтор(замыкание), то в Rust-е у нас iter может давать либо Т, либо Result<T,MQError>, в зависимости о того, с какой последовательностью мы работаем. И замыкание будет получать либо T, либо Result<T,MQError>.

Да, в этом случае исключения удобней. Но сама логика таких последовательностей не самая рядовая.

Да это очевидно было. Тут вопрос несколько в другой плоскости: есть ряд областей, где нормальной альтернативы исключениям нет. Одна из таких областей — это перегрузка операторов (например, арифметических). Вторая — это обобщенное программирование.

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

Еще было бы интересно посмотреть, как на кодах ошибок будут выглядеть аналоги C++ного accumulate

Коряво будет. Потому что Си++ accumulate, внезапно, сделан с расчетом на использование исключений. Если сравнивать Rust и Си++ по маленьким кусочкам кода, которые закладываются на специфические возможности Си++, то, естественно, получишь вывод о полном преимуществе последнего.

- исключение бросает [...]

- исключение бросает [...]

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

в Rust-е у нас iter может давать либо Т, либо Result<T,MQError>

Option<T>, если моя память мне ни с кем не изменяет (хотя, наверное, T может быть Result<T, MQError>).

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

И замыкание будет получать либо T, либо Result<T,MQError>.

Замыкание в любом случае получает T. Но T может быть равно Result<MQ, MQError>. Там, где мы пишем замыкание, нам это известно, поэтому мы можем обработать эту ситуацию.

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

есть ряд областей, где нормальной альтернативы исключениям нет. Одна из таких областей — это перегрузка операторов (например, арифметических). Вторая — это обобщенное программирование.

В Rust обобщенное программирование везде, а исключений нет.

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

Вот вариант https://is.gd/bXf6sw ,где возвращаемая ошибка содержит последовательность успешно полученных MQ-заголовках.

На С++ пришлось бы отказываться от fold и заниматься перехватом исключений.

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

Заметь, что тебе пришлось словами описывать

Словами мне пришлось описывать малолетнему дебилу очевидные вещи. В синтаксисе современного C++ бросание/небросание исключений выражается посредством noexcept.

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

Впрочем, вру. Result в Rust и исключения в С++ по функциональности практически одинаковы. В случае, когда нужно возвращать частичный результат, можно было бы написать try{}catch(){} в замыкании. Но это было бы медленнее.

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

На С++ пришлось бы отказываться от fold и заниматься перехватом исключений.

Не пришлось бы. Вы не поняли: замыканию не нужны ошибки, которые порождает итератор, ему нужны только T. То, что в Rust-е придется вместо T отдавать Result<T,MQError> — это и есть приговор для обобщенного кода.

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

Там две ссылки. Во второй эти макросы могу раскрываться в ничто.

Откуда получаются две возможные ситуации, если Qt скомпилирован без поддержки исключений:

1. Вся программа скомпилирована без поддержки исключений. В этом случае любой неудачный alloc, вернувший 0, грохает все приложение. Все. Даже если этот alloc возник при формировании какого-нибудь диагностического сообщения.

2. Программа скомпилирована с поддержкой исключений. И в QVector помещается объект с бросающим исключения конструктором копирования.

Полагаю, вы работаете по первому сценарию и вас это не просто устраивает, вы гордитесь этим.

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

Это вы не поняли. Задача. Итератор возвращает MQ или кидает исключение. Нужно вернуть массив успешно полученных MQ, изменяя только замыкание. На С++, это не сделать никак, именно потому, что исключение проходит мимо замыкания. Вот и всё обобщенное программирование.

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

fail fast & don't panic

Исключения имеют смысл в языках с навороченным ООП, типа C++. Rust же прямой как палка, исключения в нем были бы как собаке пятая нога.

исключения, ИМХО, плохо сообразуются с моделью памяти Rust machine (по аналогии с С machine) — в которой явно прописано, что а) многопоточность таки есть б) fail fast, в стиле Erlang.

потому и паника в селе: что восстановление после сбоев невозможно и нинужно — можно лишь только упасть, нанеся максимально положенный ущерб.

да здравствует Nemhain, богиня войны и паники, Леди Озера, одолжившая (borrow/lend semantic) Эксалибур самому Артуру!!!

Леди Удача ведёт нас, вооружённых Гейсами std::panic, и когда придёт всему срок и окончатся наши lifetimes, мы ещё услышим её пестню в чертогах Валгаллы !!!

Во славу превеликой Дон и всех высших sidhe! О Элберет Гилтониэль!

P.S. если же нужно восстановиться после сбоев, тут начинаются особенности: например, rescue/retry в Eiffel, учитывающий контракты и восстанавливающий инварианты классов; сигнальный протокол ошибок, наконец.

в общем, в стиле Ada/C++/Java — не лучший способ.

в сигнальном протоколе ошибок хотя бы стек не разматывается, и можно перезапустить рестарт с любого места, восстановив нужные инварианты. опять же, политика и механизхм обработки ошибок разделены как условия и рестарты — и в итоге приводят к более правильной, модульной архитектуре. опять же, метаобъектный протокол и :before/:after/:around комбинаторы методов.

конечно, с овладеванием borrow/lend semantic, lifetime, продолжениями и замыканиями, зелёными потоками и ядрёными нитями соблюдеть все эти инварианты есть более хитрый гейс.

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

а ниасилившим сиё колдовство высших sidhe — панику в селе!

во славу богини Неметоны! vae victis!

Faugh A Ballagh ! Tiocfaidh ár lá !!!

Gurth gothrim Tel’Quessir! Amin khiluva lle a’ gurtha ar’ thar !!!

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

Да, не эквивалентный, потому что там черт знает что: концепция языка отброшена.

Какая именно концепция?

Я вижу лишь вручную реализованные .filter_map() и .collect() в виде функции.

Ну значит присмотрись получше.

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

В синтаксисе современного C++ бросание/небросание исключений выражается посредством noexcept.

А отсутствие noexcept не выражает ничего.

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

Не пришлось бы. Вы не поняли: замыканию не нужны ошибки, которые порождает итератор, ему нужны только T. То, что в Rust-е придется вместо T отдавать Result<T,MQError> — это и есть приговор для обобщенного кода.

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

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

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

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

Исправленный код

И всё равно не эквивалентный.

fold_result при первой же Err прекращает итерацию и возвращает ошибку.

Твой вариант с fold при первой ошибке “запоминает” эту ошибку, после этого продолжает перебирать итератор до конца (которого может и не быть), а в конце возвращает ошибку.

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

Какая именно концепция?

Концепция итераторов. Вопрос стоял о исключениях в монадах и как это будет работать с аналогом плюсового accumulate. Пример это наглядно демонстрирует.

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