Golang Дайджест
8.25K subscribers
40 photos
1 file
189 links
Самое интересное из мира Go: новости, статьи, проекты, сервисы, изменения в языке и др.

Посты публикуются не часто - только самое важное, с чем я лично ознакомился.

Поэтому можно не мьютить канал =)

Обратная связь: @justskiv
Download Telegram
if err != nil: почему мы (не) любим обработку ошибок в Go? Обзор предложений по её улучшению

https://habr.com/ru/companies/avito/articles/944824/

Павел Агалецкий из Авито в очередной раз поднимает вечную холиварную тему — обработку ошибок в Go.

Суть проблемы (а вдруг кто-то не в курсе? 🙃):

Go не использует исключения (exceptions) — ошибки это просто значения, которые функции возвращают наравне с другими. Код выглядит многословно:

func doSomething() error {
if err := one(); err != nil {
return err
}
if err := two(); err != nil {
return err
}
if err := three(); err != nil {
return err
}
return nil
}


Сравнение с другими языками:

- Python — исключения есть, но из сигнатуры непонятно, выбрасывает метод исключение или нет
- Java — есть checked exceptions, но большинство функций в языке и библиотеках их не декларируют, т.к. это необязательно
- Rust — есть тип Result<T, E> и оператор ? для проброса ошибок (более компактно)

Что было предложено за годы существования Go:

На GitHub 195 закрытых и 14 открытых proposal по улучшению обработки ошибок. Автор группирует их:

1. check/handle — специальные ключевые слова, чтобы обрабатывать ошибки единообразно
2. try/catch — как в других языках
3. Спецсимволы (? или !) — вместо ключевых слов
4. Упрощение if — тернарные операторы и подобное

Все отклонялись по схожим причинам:
- Можно частично реализовать в userland (через panic/recover + defer)
- Ломается при оборачивании ошибок (fmt.Errorf)
- Появляется неявный control flow
- Код становится менее читаемым

Последний proposal от Ian Lance Taylor:

Ян предложил писать знак вопроса после функций, возвращающих ошибки:

func doSomething(in Dto) (err error) {
validate(in) ?
one() ?
two() ?
three() ?
return nil
}


С возможностью обработки:

validate(in) ? {
return fmt.Errorf("validation failed: %w", err)
}


Реакция сообщества неоднозначная, больше против. Дизлайков в полтора раза больше лайков.

Финал истории:

Robert Griesemer опубликовал статью в блоге Go, где команда объявила, что они больше не будут рассматривать предложения по изменению обработки ошибок. Решили, что на этапе создания языка стоило подумать лучше, но сейчас менять поздно — будет только хуже.

————

Автор делает правильные выводы:
Ошибки как обычные значения — это нормально, явная сигнатура — это хорошо, отсутствие исключений — это прекрасно. Да, многословно, но явно. Да, занимает много места, но зато всё понятно. А современные IDE с autocomplete (особенно с LLM) и code folding помогают справляться с многословностью (у меня в IDE вообще давно настроен хоткей для создания error handling блока: CMD + J).

Я полностью согласен. Лучше писать чуть больше, но понимать что происходит, чем получить "волшебный" синтаксис, который будет работать неявно. Go Team приняли мудрое решение — оставить всё как есть. Язык не должен становиться зоопарком из разных способов сделать одно и то же.

Да, в первые годы работы с Go мне тоже хотелось всячески его "облагородить", изобретать разные способы "упрощения" работы с ошибками, но со временем это проходит
🙃

P.S. Мне кажется, что все эти годы сообщество пытается запихнуть в Go механики из других языков, вместо того чтобы просто принять философию Go 🤡

#article #error_handling #proposals
Please open Telegram to view this post
VIEW IN TELEGRAM
36👍23