Обновить

Комментарии 2

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

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

Когда мы пишем обычный код на C++, нам это в голову не придёт. В Rust та же история: Drop не может вернуть ошибку

Если вас так интересуют ошибки из close, то его вызов должен осуществляться не в деструкторе, а в отдельном методе класса-обёртки. Деструктор предназначен для удаления объекта, а не для обработки ошибок. Результат его работы - отсутвие объекта и освобождённая память/хэндлы.

, и File молча проглатывает ошибку закрытия. То есть автоматический деструктор прячет не только забытый close(), но и вопрос, валиден ли файл.

Так в Си он также молча её проглатывает. Да он возвращает -1 из вызова и складирует информацию об ошибке в thread-local контекст errno, но он об этом никак не сигнализирует. Неизбежно возникает ситуация с обращением к некоторому глобальному контексту. Что противоречит следующему утверждению про явный контекст. И Rust и C++ имеют ровно те же механизмы проверки ошибок что и у C - Error::last_os_error(); также вернёт контент errno, а в С++ тот же C API.

те же отношения привычным способом.

привычный - не значит правильный. мантра джависта Uncle Bob с его "Чистым кодом" не гарантирует производительность при предлагаемой им организации - можно посмотреть на выступления того же Кейси Муратори (Big OOPs, например). А производительность неизбежно вносит сложность в сопровождение и обнуляет многие постулаты о чистом коде как максимально неэффективные. Тут начинаются сталкиваться Relation Driven и Data Driven подходы - первый нацелен на те самые привычные отношения между объектами, второй - на потоки данных, которые происходят МЕЖДУ объектами.

А как бы это выглядело на C/Rust?

На ржавый аналог смотреть хорошо, если позволяет типизация. Смотреть на Си стоит только в случае если есть необходимость разобраться как это работает на максимально низком уровне. В остальном - шабливая типизация Си будет только во вред - неявные касты типов, отсутсвие строгих булевых типов и enum, даже NULL и тот ненастоящий. С++ у себя это отчасти пофиксила, хотя всё ещё страдает от легаси Си - добавили nullptr, non-null указатели aka lvalue-ссылки, enum class, но bool по прежнему удовлетворяет std::is_integral. Rust в этом плане навел большё пользы, сделав нормальные обертки над системными API, которые позволяют работать с ними как в Си, но полностью в локальном контексте.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации