Come evitare il fastidioso errore "dichiarato e non utilizzato"


238

Sto imparando Go ma sento che è un po 'fastidioso che durante la compilazione non debba lasciare inutilizzata alcuna variabile o pacchetto.

Questo mi sta davvero rallentando. Ad esempio, volevo solo dichiarare un nuovo pacchetto e pianificare di usarlo in un secondo momento o semplicemente decommentare alcuni comandi per testare. Ricevo sempre l'errore e devo andare a commentare tutti quegli usi.

Esiste un modo per evitare questo tipo di controllo in Go?


1
Puoi anche utilizzare goimports ( godoc.org/code.google.com/p/go.tools/cmd/goimports ) per aggiungere / rimuovere automaticamente le importazioni.
elithrar,


3
Sento ancora che un'opzione del compilatore sarebbe utile per il flusso di lavoro "Voglio commentare qualcosa per facilitare il debug".
RJFalconer,

13
Questa funzione è un ottimo modo per perdere tempo nelle persone, qual è il punto? Quando si impegna / spedisce il codice, ok nessun vars inutilizzato è bello, ma quando lo si sviluppa? Orribile.
Alexander Mills,

È il 2020 e non riesco a credere che non abbiano ancora risolto questo problema (nemmeno con una bandiera del compilatore). Ho fatto un progetto su Go circa 5 anni fa e nel complesso mi è piaciuta la lingua, ma era inutilizzabile per me solo per questo. Il modo in cui codifico continuo a commentare / commentare cose, quindi questa "caratteristica" in Go fa sì che le cose richiedano il doppio del tempo per me ... Ho controllato ogni pochi mesi da allora per vedere se un senso della ragione ha superato la squadra Go, e finora nessuna fortuna ... Fa schifo. Altrimenti è una lingua fantastica e mi piacerebbe usarla di più, ma al momento non è utilizzabile per me.
Ruslan,

Risposte:


235

Quell'errore è qui per costringerti a scrivere codice migliore e assicurarti di usare tutto ciò che dichiari o importi. Semplifica la lettura del codice scritto da altre persone (sei sempre sicuro che verranno utilizzate tutte le variabili dichiarate) ed evita alcuni possibili codici morti.

Ma, se vuoi davvero saltare questo errore, puoi usare l' identificatore vuoto ( _):

package main

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

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

diventa

package main

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

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

Come detto da kostix nei commenti qui sotto, puoi trovare la posizione ufficiale del team Go nelle FAQ :

La presenza di una variabile non utilizzata può indicare un errore, mentre le importazioni non utilizzate rallentano la compilazione. Accumula abbastanza importazioni non utilizzate nella tua struttura di codice e le cose possono andare molto lentamente. Per questi motivi, Go non consente nessuno dei due.


90
Tuttavia, questo non è così diverso dal commentarlo. E capisco che questo è per un codice migliore, ma sarebbe meglio se possiamo chiudere un controllo perché testare il nostro codice e quindi riaprire questo controllo dopo che vogliamo finire il codice e renderlo pulito?
A-letubby,

21
@kostix Beh .. potrebbe non rallentarti perché potresti essere un esperto, ma è per me e per il modo in cui sto programmando. Mi chiedo solo se esiste un modo migliore. Ma comunque, grazie per le FAQ! Leggendo questo, posso capire totalmente per quali motivi Golang sta facendo in questo modo.
A-letubby,

20
Esiste un argomento da riga di comando per disattivarlo? O questa è una caratteristica immutabile?
Ethan Bierlein,

26
FWIW, ho avuto brutti momenti nel leggere il codice di altri, ma sicuramente non a causa di simboli inutilizzati. OTOH, oggi ho perso un'ora studiando i metodi per gestire questa "caratteristica" * #% $ golang.
Torsten Bronger,

24
Purtroppo questa risposta è corretta, ma ciò non lo giustifica. C'è un mondo di differenza tra il check-in del codice e la semplice esecuzione. Quando eseguiamo il check in del codice, utilizziamo le linter per rilevare questo tipo di errore. Quando eseguiamo durante un rapido sviluppo, non abbiamo gli stessi standard. È imperdonabile confondere un compilatore con una linter. Anche la polizia di stile all'interno di Google non commette questo errore.
Travis Wilson,

29

A tale scopo è possibile utilizzare una semplice "funzione null", ad esempio:

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

Che puoi usare così:

package main

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

    Use(a, b, c)
}

C'è anche un pacchetto per questo, quindi non è necessario definire la Usefunzione ogni volta:

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

func main() {
  // [..]

  xulu.Use(a, b, c)
}

29

Secondo le FAQ :

Alcuni hanno chiesto un'opzione del compilatore per disattivare quei controlli o almeno ridurli in avvisi. Tale opzione non è stata aggiunta, tuttavia, perché le opzioni del compilatore non dovrebbero influire sulla semantica della lingua e perché il compilatore Go non riporta avvisi, ma solo errori che impediscono la compilazione.

Esistono due motivi per non avere avvisi. Innanzitutto, se vale la pena lamentarsi, vale la pena correggerlo nel codice. (E se non vale la pena aggiustarlo, non vale la pena menzionarlo.) Secondo, fare in modo che il compilatore generi avvisi incoraggia l'implementazione a mettere in guardia su casi deboli che possono rendere rumorosa la compilazione, mascherando errori reali che dovrebbero essere corretti.

Non sono necessariamente d'accordo con questo per vari motivi che non vale la pena approfondire. È quello che è, e non è probabile che cambi nel prossimo futuro.

Per i pacchetti, c'è lo goimportsstrumento che aggiunge automaticamente i pacchetti mancanti e rimuove quelli inutilizzati. Per esempio:

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

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

Dovresti essere in grado di eseguirlo da qualsiasi editor decente a metà strada, ad esempio per Vim:

:!goimports -w %

Il goimports pagina elenca alcuni comandi per altri editor e in genere viene impostato per l'esecuzione automatica quando si salva il buffer su disco.

Si noti che goimportsverrà eseguito anche gofmt.


Come già accennato, per le variabili il modo più semplice è assegnarle (temporaneamente) a _:

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

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

_, _ = tasty, horrible

9

Un angolo non menzionato finora sono i set di strumenti utilizzati per la modifica del codice.

L'uso di Visual Studio Code insieme all'estensione di lukehoban chiamato Gofarà un po 'di magia automatica per te. L'estensione Go viene eseguita automaticamente gofmt, golintecc., Rimuove e aggiunge importvoci . Quindi almeno quella parte è ora automatica.

Devo ammettere che non è il 100% della soluzione alla domanda, ma comunque abbastanza utile.


8

Nel caso in cui altri abbiano difficoltà a dare un senso a questo, penso che potrebbe aiutare a spiegarlo in termini molto semplici. Se hai una variabile che non usi, ad esempio una funzione per la quale hai commentato l'invocazione (un caso d'uso comune):

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

È possibile assegnare una variabile inutile / vuota alla funzione in modo che non sia più inutilizzata :

myFn := func () { }
_ = myFn
// myFn()
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.