So vermeiden Sie lästige Fehler "deklariert und nicht verwendet"

236

Ich lerne Go, aber ich finde es etwas ärgerlich, dass ich beim Kompilieren keine Variablen oder Pakete unbenutzt lassen sollte.

Das verlangsamt mich wirklich ziemlich. Zum Beispiel wollte ich nur ein neues Paket deklarieren und planen, es später zu verwenden, oder einfach einen Befehl zum Testen auskommentieren. Ich bekomme immer den Fehler und muss all diese Verwendungen kommentieren.

Gibt es eine Möglichkeit, diese Art des Eincheckens in Go zu vermeiden?

A-letubby
quelle
1
Sie können auch goimports ( godoc.org/code.google.com/p/go.tools/cmd/goimports ) verwenden, um automatisch Importe für Sie hinzuzufügen / zu entfernen.
Elithrar
3
Ich bin immer noch der Meinung, dass eine Compiler-Option für den Workflow "Ich möchte etwas auskommentieren, um das Debuggen zu unterstützen" nützlich wäre.
RJFalconer
13
Diese Funktion ist eine großartige Möglichkeit, die Zeit der Leute zu verschwenden. Lol, worum geht es? Wenn Sie Code festschreiben / versenden, ist ok, keine unbenutzten Variablen sind nett, aber wenn Sie sie entwickeln? Schrecklich.
Alexander Mills
Es ist 2020 und ich kann nicht glauben, dass sie dies immer noch nicht behoben haben (nicht einmal mit einem Compiler-Flag). Ich habe vor ungefähr 5 Jahren ein Projekt in Go gemacht und insgesamt hat mir die Sprache gefallen, aber sie war allein aus diesem Grund für mich unbrauchbar. Die Art und Weise, wie ich codiere, kommentiere / kommentiere ich ständig Dinge, so dass diese "Funktion" in Go dazu führt, dass die Dinge für mich doppelt so lange dauern ... Ich habe seitdem alle paar Monate nachgesehen, ob ein Sinn für Vernunft überholt hat das Go-Team, und bisher kein Glück ... Scheiße. Ansonsten ist es eine großartige Sprache und ich würde sie gerne mehr verwenden, aber derzeit ist sie für mich einfach nicht verwendbar.
Ruslan

Antworten:

232

Dieser Fehler soll Sie dazu zwingen, besseren Code zu schreiben und alles zu verwenden, was Sie deklarieren oder importieren. Dies erleichtert das Lesen von Code, der von anderen Personen geschrieben wurde (Sie sind immer sicher, dass alle deklarierten Variablen verwendet werden), und vermeidet möglicherweise toten Code.

Wenn Sie diesen Fehler jedoch wirklich überspringen möchten, können Sie den leeren Bezeichner ( _) verwenden:

package main

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

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

wird

package main

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

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

Wie von kostix in den Kommentaren unten gesagt, finden Sie die offizielle Position des Go-Teams in den FAQ :

Das Vorhandensein einer nicht verwendeten Variablen kann auf einen Fehler hinweisen, während nicht verwendete Importe die Kompilierung nur verlangsamen. Sammeln Sie genügend nicht verwendete Importe in Ihrem Codebaum, und es kann sehr langsam werden. Aus diesen Gründen erlaubt Go beides nicht.

Florent Bayle
quelle
90
Dies unterscheidet sich jedoch nicht so sehr vom Auskommentieren. Und ich verstehe, dass dies für besseren Code ist, aber wäre es besser, wenn wir eine Prüfung schließen könnten, warum wir unseren Code testen, und diese Prüfung dann erneut öffnen können, nachdem wir den Code fertiggestellt und sauber gemacht haben möchten?
A-letubby
21
@kostix Nun ... es könnte dich nicht verlangsamen, weil du vielleicht ein Experte bist, aber es ist für mich und die Art, wie ich programmiere. Ich frage mich nur, ob es einen besseren Weg gibt. Trotzdem danke für die FAQ! Wenn ich dies lese, kann ich völlig verstehen, aus welchen Gründen Golang dies tut.
A-letubby
20
Gibt es ein Befehlszeilenargument, um dies zu deaktivieren? Oder ist dies eine unveränderliche Funktion?
Ethan Bierlein
26
FWIW, ich hatte schlechte Zeiten beim Lesen des Codes anderer, aber definitiv nicht aufgrund nicht verwendeter Symbole. OTOH, ich habe heute eine Stunde verloren, als ich nach Methoden gesucht habe, um mit dieser * #% $ golang "-Funktion" umzugehen.
Torsten Bronger
24
Leider ist diese Antwort richtig - aber das rechtfertigt es nicht. Es gibt einen großen Unterschied zwischen dem Einchecken von Code und dem einfachen Ausführen von Code. Wenn wir Code einchecken, verwenden wir Linters, um diese Art von Fehler abzufangen. Wenn wir während einer schnellen Entwicklung ausführen, haben wir nicht die gleichen Standards. Es ist unverzeihlich, einen Compiler mit einem Linter zu verwechseln. Selbst die Stilpolizei in Google macht diesen Fehler nicht.
Travis Wilson
29

Sie können hierfür eine einfache "Nullfunktion" verwenden, zum Beispiel:

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

Was Sie so verwenden können:

package main

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

    Use(a, b, c)
}

Es gibt auch ein Paket dafür, damit Sie die UseFunktion nicht jedes Mal definieren müssen:

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

func main() {
  // [..]

  xulu.Use(a, b, c)
}
lunux2008
quelle
29

Laut FAQ :

Einige haben nach einer Compiler-Option gefragt, um diese Überprüfungen zu deaktivieren oder zumindest auf Warnungen zu reduzieren. Eine solche Option wurde jedoch nicht hinzugefügt, da Compileroptionen die Semantik der Sprache nicht beeinflussen sollten und der Go-Compiler keine Warnungen meldet, sondern nur Fehler, die die Kompilierung verhindern.

Es gibt zwei Gründe, warum keine Warnungen vorliegen. Erstens, wenn es sich lohnt, sich zu beschweren, lohnt es sich, dies im Code zu korrigieren. (Und wenn es sich nicht lohnt, das Problem zu beheben, ist es auch nicht erwähnenswert.) Zweitens wird die Implementierung durch das Generieren von Warnungen durch den Compiler dazu ermutigt, vor schwachen Fällen zu warnen, die die Kompilierung verrauschen lassen und echte Fehler maskieren können, die behoben werden sollten.

Ich stimme dem aus verschiedenen Gründen nicht unbedingt zu, die es nicht wert sind, darauf einzugehen. Es ist, was es ist, und es wird sich in naher Zukunft wahrscheinlich nicht ändern.

Für Pakete gibt es das goimportsTool, das fehlende Pakete automatisch hinzufügt und nicht verwendete entfernt. Beispielsweise:

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

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

Sie sollten in der Lage sein, dies von jedem halbwegs anständigen Editor aus auszuführen - zum Beispiel für Vim:

:!goimports -w %

Auf der goimportsSeite werden einige Befehle für andere Editoren aufgelistet. Normalerweise legen Sie fest, dass sie automatisch ausgeführt werden, wenn Sie den Puffer auf der Festplatte speichern.

Beachten Sie, dass goimportsauch ausgeführt wird gofmt.


Wie bereits erwähnt, ist es für Variablen am einfachsten, sie (vorübergehend) zuzuweisen _:

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

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

_, _ = tasty, horrible
Martin Tournoij
quelle
9

Ein Winkel, der bisher nicht erwähnt wurde, sind Werkzeugsätze, die zum Bearbeiten des Codes verwendet werden.

Die Verwendung von Visual Studio Code zusammen mit der aufgerufenen Erweiterung von lukehoban bewirktGo eine gewisse automatische Magie für Sie. Die Go - Erweiterung automatisch läuft gofmt, golintetc, und entfernt und fügt importEinträge . Zumindest dieser Teil ist jetzt automatisch.

Ich gebe zu, dass es nicht 100% der Lösung der Frage ist, aber dennoch nützlich genug.

miltonb
quelle
8

Für den Fall, dass andere Schwierigkeiten haben, dies zu verstehen, könnte es hilfreich sein, dies in sehr einfachen Worten zu erklären. Wenn Sie eine Variable haben, die Sie nicht verwenden, z. B. eine Funktion, für die Sie den Aufruf auskommentiert haben (ein häufiger Anwendungsfall):

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

Sie können eine nutzlose / leeren Variable an die Funktion zuweisen , so dass es nicht mehr ungenutzt :

myFn := func () { }
_ = myFn
// myFn()
Max Pleaner
quelle