Comment éviter une erreur gênante «déclarée et non utilisée»


238

J'apprends Go, mais je pense qu'il est un peu ennuyeux de ne pas laisser de variable ou de package inutilisé lors de la compilation.

Cela me ralentit vraiment. Par exemple, je voulais simplement déclarer un nouveau package et planifier de l'utiliser plus tard ou simplement décommenter une commande à tester. J'ai toujours l'erreur et je dois commenter toutes ces utilisations.

Existe-t-il un moyen d'éviter ce type d'enregistrement dans Go?


1
Vous pouvez également utiliser goimports ( godoc.org/code.google.com/p/go.tools/cmd/goimports ) pour ajouter / supprimer automatiquement des importations pour vous.
elithrar


3
Je pense toujours qu'une option de compilation serait utile pour le flux de travail "Je veux commenter quelque chose pour faciliter le débogage".
RJFalconer

13
Cette fonctionnalité est un excellent moyen de perdre du temps, lol, à quoi ça sert? Lorsque vous validez / expédiez du code, ok aucun vars inutilisé n'est bien, mais lors du développement? Horrible.
Alexander Mills

Nous sommes en 2020 et je ne peux pas croire qu'ils n'aient toujours pas corrigé cela (pas même avec un drapeau de compilation). J'ai fait un projet à Go il y a environ 5 ans et dans l'ensemble, j'ai aimé la langue, mais elle était inutilisable pour moi uniquement à cause de cela. La façon dont je code je commente / commente constamment les choses, donc cette "fonctionnalité" dans Go fait que les choses prennent deux fois plus de temps pour moi ... Je vérifie depuis quelques mois depuis pour voir si un sens de la raison a dépassé l'équipe Go, et jusqu'à présent pas de chance ... Suce. C'est une langue géniale autrement et j'adorerais l'utiliser davantage, mais actuellement elle n'est tout simplement pas utilisable pour moi.
Ruslan

Réponses:


235

Cette erreur est là pour vous forcer à écrire un meilleur code et à utiliser tout ce que vous déclarez ou importez. Cela facilite la lecture du code écrit par d'autres personnes (vous êtes toujours sûr que toutes les variables déclarées seront utilisées) et évite un code mort possible.

Mais, si vous voulez vraiment ignorer cette erreur, vous pouvez utiliser l' identifiant vide ( _):

package main

import (
    "fmt" // imported and not used: "fmt"
)

func main() {
    i := 1 // i declared and not used
}

devient

package main

import (
    _ "fmt" // no more error
)

func main() {
    i := 1 // no more error
    _ = i
}

Comme dit par kostix dans les commentaires ci-dessous, vous pouvez retrouver la position officielle de l'équipe Go dans la FAQ :

La présence d'une variable inutilisée peut indiquer un bogue, tandis que les importations inutilisées ralentissent simplement la compilation. Accumulez suffisamment d'importations inutilisées dans votre arborescence de code et les choses peuvent devenir très lentes. Pour ces raisons, Go n'autorise ni l'un ni l'autre.


90
Pourtant, ce n'est pas si différent que de le commenter. Et, je comprends que c'est pour un meilleur code mais serait-il préférable que nous puissions fermer une vérification pourquoi tester sur notre code, puis rouvrir cette vérification après avoir voulu terminer le code et le nettoyer?
A-letubby

21
@kostix Eh bien .. cela ne vous ralentira peut-être pas parce que vous pourriez être un expert, mais c'est pour moi et la façon dont je code. Je me demande simplement s'il y a une meilleure façon. Mais de toute façon, merci pour la FAQ! En lisant ceci, je peux totalement comprendre pour quelles raisons golang fait de cette façon.
A-letubby

20
Existe-t-il un argument de ligne de commande pour désactiver cette option? Ou s'agit-il d'une fonctionnalité inchangeable?
Ethan Bierlein

26
FWIW, j'ai eu du mal à lire le code des autres, mais certainement pas à cause des symboles inutilisés. OTOH, j'ai perdu une heure aujourd'hui à enquêter sur les méthodes pour gérer cette "fonctionnalité" * #% $ golang.
Torsten Bronger

24
Malheureusement, cette réponse est correcte - mais cela ne la justifie pas. Il y a un monde de différence entre archiver du code et simplement l'exécuter. Lorsque nous archivons le code, nous utilisons des linters pour détecter ce type d'erreur. Lorsque nous exécutons pendant un développement rapide, nous n'avons pas les mêmes normes. Il est impardonnable de confondre un compilateur avec un linter. Même la police de style de Google ne fait pas cette erreur.
Travis Wilson

29

Vous pouvez utiliser une simple "fonction null" pour cela, par exemple:

func Use(vals ...interface{}) {
    for _, val := range vals {
        _ = val
    }
}

Que vous pouvez utiliser comme ceci:

package main

func main() {
    a := "declared and not used"
    b := "another declared and not used"
    c := 123

    Use(a, b, c)
}

Il existe également un package pour cela , vous n'avez donc pas à définir la Usefonction à chaque fois:

import (
  "github.com/lunux2008/xulu"
)

func main() {
  // [..]

  xulu.Use(a, b, c)
}

29

Selon la FAQ :

Certains ont demandé une option de compilation pour désactiver ces vérifications ou au moins les réduire à des avertissements. Une telle option n'a pas été ajoutée, cependant, car les options du compilateur ne devraient pas affecter la sémantique du langage et parce que le compilateur Go ne signale pas les avertissements, seulement les erreurs qui empêchent la compilation.

Il y a deux raisons de ne pas avoir d'avertissement. Tout d'abord, si cela vaut la peine de se plaindre, cela vaut la peine d'être corrigé dans le code. (Et si cela ne vaut pas la peine d'être corrigé, cela ne vaut pas la peine d'être mentionné.) Deuxièmement, le fait que le compilateur génère des avertissements encourage la mise en œuvre à avertir des cas faibles qui peuvent rendre la compilation bruyante, masquant les vraies erreurs qui devraient être corrigées.

Je ne suis pas nécessairement d'accord avec cela pour diverses raisons qui ne valent pas la peine d'être abordées. C'est ce qu'il est et il est peu probable qu'il change dans un avenir proche.

Pour les packages, il existe l' goimportsoutil qui ajoute automatiquement les packages manquants et supprime ceux qui ne sont pas utilisés. Par exemple:

# Install it
$ go get golang.org/x/tools/cmd/goimports

# -w to write the source file instead of stdout
$ goimports -w my_file.go

Vous devriez pouvoir l'exécuter à partir de n'importe quel éditeur décent à mi-chemin - par exemple pour Vim:

:!goimports -w %

La goimportspage répertorie certaines commandes pour d'autres éditeurs et vous la définissez généralement pour qu'elle s'exécute automatiquement lorsque vous enregistrez le tampon sur le disque.

Notez que goimportscela fonctionnera également gofmt.


Comme cela a déjà été mentionné, pour les variables, le moyen le plus simple consiste à les affecter (temporairement) à _:

// No errors
tasty := "ice cream"
horrible := "marmite"

// Commented out for debugging
//eat(tasty, horrible)

_, _ = tasty, horrible

9

Un angle non mentionné jusqu'à présent est les ensembles d'outils utilisés pour éditer le code.

L'utilisation de Visual Studio Code avec l'extension de lukehoban appelée Gofera de la magie automatique pour vous. L'extension Go s'exécute automatiquement gofmt, golintetc., et supprime et ajoute des importentrées . Donc, au moins, cette partie est maintenant automatique.

J'admettrai que ce n'est pas 100% de la solution à la question, mais cependant assez utile.


8

Au cas où d'autres auraient du mal à comprendre cela, je pense que cela pourrait aider à l'expliquer en termes très simples. Si vous avez une variable que vous n'utilisez pas, par exemple une fonction pour laquelle vous avez commenté l'invocation (un cas d'utilisation courant):

myFn := func () { }
// myFn()

Vous pouvez affecter une variable inutile / vide à la fonction afin qu'elle ne soit plus inutilisée :

myFn := func () { }
_ = myFn
// myFn()
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.