The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]



Индекс форумов
Составление сообщения

Исходное сообщение
"Выпуск языка программирования Rust 1.43"
Отправлено Ordu, 25-Апр-20 05:48 
> Исключения и явный возврат ошибок в расте принципиально мало отличаются. Это вопрос
> реализации.
> Представь себе, что добавили конструкцию try catch в rust в виде синтаксического
> сахара поверх обычного механизма Result.

Не получится. Одна из основных задач Result -- помочь программисту не забыть обработать ошибки: ты не сможешь добраться до значения, которое вернула функция, не распаковав обёртку из Result'а. Кроме того, тип Result'а может меняться по мере последовательных возвратов: ? проверяет Result, и если он Err, то он либо возвращает его как есть, либо если возвращаемый тип ошибки отличается от того, который в наличии, он пытается сделать from -- то есть сгенерить ошибку нужного типа, из той, что прилетела.

try/catch ты можешь не писать, и исключение продолжит разматывать стек. Result ты не можешь не развернуть, если хочешь работать с результатом функции. Чтобы такое было возможно, компилятор должен генерить всякий специальный код, который будет отрабатывать даже тогда, когда всё идёт норм. Я не вдавался в подробности, но, судя по всему, там нужна какая-то специальная огранизация стека. Там возникают всякие интересности, вида обработки вложенных ошибок, когда исключение вылетело в процессе размотки стека из-за другого исключения.

Передача ошибки возвращаемым значением сильно другая, стек разматывается не принудительно, Result -- это не non-local exit. throw -- это погрейженный longjmp, если присмотреться. Result -- это способ прокинуть информацию об ошибке при помощи return.

А насчёт синтаксического сахара, фишка в том, что в rust есть макрос try!, который в использовании похож на try/catch, но этот макрос заменили синтаксическим сахаром оператора ?.

> Чем тут method()?other_method()?yet_another_method()? от
> try {
> method.other_method.yet_another_method
> } catch {
> }
> Сильно различаются?

Если забить на различия в реализациях (на которые на мой взгляд нельзя забивать, они принципиально разные), то тогда отличия только в том, что try/catch многословнее и неудобнее.

В расте же я могу сделать что-то типа:

let ret = method().map_err(|_| "Method failed".to_string())?
    .other_method().map_err(|_| "Other method failed".to_string())?
    .yet_another_method().map_err(|_| "Yet another method failed".to_string())?;

После этого мой код будет выкидывать разные ошибки, в зависимости от того, в каком месте он обломался. В случае же с try/catch ты сможешь понять откуда исключение вылетело только если тебе повезёт, и эти все методы будут выкидывать разные типы исключений.

Помимо этого, Result имеет и другие методы, кроме map_err. Например ok_or_else -- если метод вернул вместо значения ошибку, я могу вызвать другой метод, который вернёт хоть какое-нибудь значение. try/catch можно использовать таким образом, но тебе придётся каждый вызов заворачивать в отдельный try/catch. Это можно, но сильно многословно.

 

Ваше сообщение
Имя*:
EMail:
Для отправки ответов на email укажите знак ! перед адресом, например, [email protected] (!! - не показывать email).
Более тонкая настройка отправки ответов производится в профиле зарегистрированного участника форума.
Заголовок*:
Сообщение*:
 
При общении не допускается: неуважительное отношение к собеседнику, хамство, унизительное обращение, ненормативная лексика, переход на личности, агрессивное поведение, обесценивание собеседника, провоцирование флейма голословными и заведомо ложными заявлениями. Не отвечайте на сообщения, явно нарушающие правила - удаляются не только сами нарушения, но и все ответы на них. Лог модерирования.



Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру