Важное правило в Go заключается в том, что вы всегда должны проверять ошибки. У большинства людей нет проблем с этим, и они правильно проверяют все свои ошибки, за исключением случаев, когда ошибка может быть вызвана отложенным методом. Этот код, например, довольно часто встречается во многих кодовых базах:

Проблема здесь в том, что мы не проверяем, действительно ли файл закрывается, и вы можете столкнуться с утечкой файлового дескриптора. После разговора с несколькими людьми основная причина, по которой они решили не проверять ошибку, заключается в повышенной многословности, в том, что ошибка «никогда не случается», что «не так уж плохо», или потому, что «в случае сбоя мы ничего не можем сделать. в любом случае, и код уже сделал то, что должен был делать ». Хотя в этом есть доля правды, ни одна из этих причин не является действительной. Лучше явно предотвратить выход из приложения известной ошибки, чем игнорировать ее. Это означает, что вы должны как минимум зарегистрировать ошибку.

К счастью для нас, есть несколько способов проверить ошибку, не усложняя код. Самый распространенный способ сделать это - дважды закрыть файл:

В этом примере вы в основном получаете лучшее из обоих миров: ошибка проверяется, и добавляется немного кода. К сожалению, это не всегда работает. Библиотеки нередко реализуютio.Closer как способ освобождения любых используемых ресурсов, но не все из них позволяют вызывать метод дважды, как это делает os.File. По соглашению я решил всегда вызывать свои методы «очистки» Close, что позволило мне создать очень простой, но мощный метод, который заботится о проверке всех отложенных ошибок без необходимости добавлять дополнительный код где-либо (кроме самого помощника):

Как видите, все, что вам нужно сделать, это заменить defer f.Close() на defer close(f, &err). Это всего на 5 символов больше, и он делает все, что вам нужно. Метод получает указатель на ошибку, и если Close() не работает, он либо присваивает значение ошибке, либо регистрирует ее. Вы также можете легко улучшить этот метод, чтобы войти в другой регистратор (или сообщить об этом в datadog, часовую и т. Д.), А также добавить трассировку стека, некоторый контекст. и Т. Д.