Я только начинаю работать с Go. В моем коде этого становится много:
if err != nil {
//handle err
}
или это
if err := rows.Scan(&some_column); err != nil {
//handle err
}
Есть ли какие-нибудь хорошие идиомы / стратегии / лучшие практики для проверки и обработки ошибок в Go?
ИЗМЕНИТЬ, чтобы уточнить: я не кричу и не предлагаю команде Go придумать что-то получше. Я спрашиваю, правильно ли я делаю или я пропустил какую-то технику, которую придумало сообщество. Спасибо всем.
Ответы:
Ваш код идиоматичен, и, на мой взгляд, это лучшая доступная практика. Некоторые наверняка не согласятся, но я бы сказал, что это стиль, встречающийся во всех стандартных библиотеках Golang . Другими словами, авторы Go так пишут обработку ошибок.
источник
Через шесть месяцев после того, как этот вопрос был задан, Роб Пайк написал в блоге сообщение под названием « Ошибки - это ценности» .
Там он утверждает, что вам не нужно программировать способом, представленным OP, и упоминает несколько мест в стандартной библиотеке, где они используют другой шаблон.
Это хорошее чтение.
источник
Я согласен с ответом jnml, что они оба являются идиоматическим кодом, и добавлю следующее:
Ваш первый пример:
более идиоматичен при работе с более чем одним возвращаемым значением. например:
Ваш второй пример - хорошее сокращение, когда вы имеете дело только со
err
значением. Это применимо, если функция возвращает толькоerror
, или если вы намеренно игнорируете возвращаемые значения, кромеerror
. В качестве примера, это иногда используется сReader
иWriter
функциями , которые возвращаютint
из числа записанных байт (иногда ненужной информации) , а такжеerror
:Вторая форма называется использованием оператора инициализации if .
Итак, что касается лучших практик, насколько мне известно (за исключением использования пакета «errors» для создания новых ошибок, когда они вам нужны), вы охватили почти все, что вам нужно знать об ошибках в Go!
EDIT: Если вы обнаружили , что на самом деле не может жить без исключений, вы можете имитировать их
defer
,panic
иrecover
.источник
Я создал библиотеку для упрощенной обработки ошибок и передачи по очереди функций Go.
Вы можете найти его здесь: https://github.com/go-on/queue
Он имеет компактный и многословный синтаксический вариант. Вот пример короткого синтаксиса:
Имейте в виду, что есть небольшие накладные расходы на производительность, так как он использует отражение.
Кроме того, это не идиоматический код go, поэтому вы захотите использовать его в своих собственных проектах или если ваша команда согласится использовать его.
источник
«Стратегия» обработки ошибок в golang и других языках состоит в том, чтобы постоянно распространять ошибки вверх по стеку вызовов, пока вы не достигнете в стеке вызовов достаточно высокого уровня для обработки этой ошибки. Если вы попытались обработать эту ошибку слишком рано, то, скорее всего, в конечном итоге код повторится. Если вы справитесь с этим слишком поздно, вы что-то сломаете в своем коде. Golang делает этот процесс очень простым, поскольку он очень четко показывает, обрабатываете ли вы ошибку в данном месте или распространяете ее.
Если вы собираетесь игнорировать ошибку, простой _ очень ясно покажет этот факт. Если вы обрабатываете ее, то ясно, какой именно случай ошибки вы обрабатываете, поскольку вы проверите ее в операторе if.
Как было сказано выше, ошибка на самом деле является нормальным значением. Это относится к нему как к такому.
источник
Боги Go опубликовали «черновой вариант» обработки ошибок в Go 2. Он направлен на изменение идиомы ошибок:
Обзор и дизайн
Им нужна обратная связь от пользователей!
Обратная связь вики
Вкратце это выглядит так:
ОБНОВЛЕНИЕ. Эскизный проект получил много критики, поэтому я составил « Требования, которые следует учитывать при обработке ошибок Go 2» с меню возможностей для возможного решения.
источник
Большинство в отрасли следуют стандартным правилам, упомянутым в документации golang. Обработка ошибок и Go . И это также помогает создавать документы для проекта.
источник
Ниже я расскажу о сокращении обработки ошибок для Go, образец предназначен для получения параметров URL-адреса HTTP:
(Шаблон проектирования взят из https://blog.golang.org/errors-are-values )
вызов его для нескольких возможных параметров будет следующим:
Это не серебряная пуля, недостатком является то, что если у вас было несколько ошибок, вы можете получить только последнюю ошибку.
Но в данном случае это относительно однообразная повторяемость и низкий риск, поэтому я могу просто получить последнюю возможную ошибку.
источник
Вы можете очистить свой код обработки ошибок для подобных ошибок (поскольку ошибки - это значения, с которыми вы должны быть осторожны здесь) и написать функцию, которую вы вызываете с переданной ошибкой для обработки ошибки. Тогда вам не придется каждый раз писать «if err! = Nil {}». Опять же, это приведет только к очистке кода, но я не думаю, что это идиоматический способ делать что-то.
Опять же, то, что вы можете , не означает, что вы должны .
источник
goerr позволяет обрабатывать ошибки с помощью функций
источник
Если вам нужен точный контроль ошибок, это может не быть решением, но для меня в большинстве случаев любая ошибка является препятствием для шоу.
Поэтому вместо этого я использую функции.
источник
stderr
а неstdout
, поэтому просто используйтеlog.Fatal(err)
илиlog.Fatalln("some message:", err)
. Поскольку почти ничто иное, какmain
принятие такого решения о завершении всей программы (т.е. возвращать ошибки из функций / методов, не прерывать), в редких случаях это то, что вы хотите сделать, это чище и лучше сделать это явно (т.е.if err := someFunc(); err != nil { log.Fatal(err) }
), а не с помощью «вспомогательной» функции, которая не понимает, что она делает (имя «Err» нехорошее, оно не указывает на то, что может завершить программу).