2016-11-03 4 views
1

gometalinter et errcheck renvoyez-moi un avertissement concernant le renvoi d'une fonction qui renvoie une variable.gometalinter/errcheck renvoie un avertissement sur le report d'une fonction qui renvoie une variable

Exemple dans une requête Web:

defer r.Body.Close() 

Dans ce cas Close, retourne une variable d'erreur et il est pas cochée.

La meilleure méthode/idiomatique est-elle de la reporter dans une autre fonction?

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

Répondre

6

Si une fonction différée a des valeurs de retour, ils sont mis au rebut lorsque la fonction complète (pour plus de détails, consultez Spec: Defer statements). Donc la seule façon de vérifier la valeur de retour est de la stocker, et cela n'est possible que si la fonction elle-même est différée, mais une autre fonction qui l'appelle.

Une façon de le faire est d'utiliser une fonction anonyme que vous avez fait, ce qui peut être légèrement simplifié:

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

Ou vous pouvez créer une fonction d'assistance pour elle:

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

Et en utilisant il:

defer Check(r.Body.Close) 

La fonction d'aide bien sûr peut être utilisé plusieurs fois, par exemple:

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

que vous pouvez également créer une fonction d'assistance modifiée, ce qui peut accepter plusieurs fonctions:

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

Et l'utiliser:

defer Checks(r.Body.Close, SomeOtherFunc) 

Notez que je intentionnellement une boucle vers le bas dans Checks() pour imiter le premier-entré-dernier-dehors nature de l'exécution des fonctions différées, car le dernier defer sera exec En utilisant une boucle descendante, la dernière valeur de la fonction passée à Checks() sera exécutée en premier.