gometalinter / errcheck возвращает предупреждение об отсрочке функции, которая возвращает переменную

gometalinter и errcheck возвращают мне предупреждение об отсрочке функции, которая возвращает переменную.

Пример в веб-запросе:

defer r.Body.Close()

В этом случае Close возвращает переменную ошибки, и она не проверяется.

Является ли лучший метод/идиоматический способ отложить его внутри другой функции?

defer func() {
    err := r.Body.Close()
    if err != nil {
        // fmt, panic or whatever
    }
}()

person Andrea Sessa    schedule 03.11.2016    source источник


Ответы (1)


Если отложенная функция имеет какие-либо возвращаемые значения, они отбрасываются после завершения функции (для получения дополнительной информации см. Spec: Отложенные операторы ).

Так что единственный способ проверить возвращаемое значение — это сохранить его, а это возможно только в том случае, если отложена не сама функция, а другая функция, которая ее вызывает.

Один из способов сделать это - использовать анонимную функцию, как вы, которая может быть немного упрощена:

defer func() {
    if err := r.Body.Close(); err != nil {
        fmt.Println("Error when closing:", err)
    }
}()

Или вы можете создать для него вспомогательную функцию:

func Check(f func() error) {
    if err := f(); err != nil {
        fmt.Println("Received error:", err)
    }
}

И используя его:

defer Check(r.Body.Close)

Вспомогательную функцию, конечно, можно использовать несколько раз, например:

defer Check(r.Body.Close)
defer Check(SomeOtherFunc)

Для чего вы также можете создать модифицированную вспомогательную функцию, которая может принимать несколько функций:

func Checks(fs ...func() error) {
    for i := len(fs) - 1; i >= 0; i-- {
        if err := fs[i](); err != nil {
            fmt.Println("Received error:", err)
        }
    }
}

И используя его:

defer Checks(r.Body.Close, SomeOtherFunc)

Обратите внимание, что я намеренно использовал нисходящий цикл в Checks(), чтобы имитировать первый вход-последний выход при выполнении отложенных функций, потому что последний defer будет выполняться первым, поэтому используется нисходящий цикл. последнее значение функции, переданное в Checks(), будет выполнено первым.

person icza    schedule 03.11.2016