Jak wyłączyć nieużywany błąd importu Golang

99

Domyślnie Go traktuje nieużywany import jako błąd, zmuszając cię do usunięcia importu. Chcę wiedzieć, czy jest jakaś nadzieja na zmianę tego zachowania, np. Zredukowanie go do ostrzeżenia.

Uważam, że ten problem jest wyjątkowo irytujący, uniemożliwiając mi cieszenie się kodowaniem w Go.

Na przykład testowałem kod, wyłączając segment / funkcję. Niektóre funkcje z biblioteki nie są już używane (np. Fmt, błędy, cokolwiek), ale będę musiał ponownie włączyć tę funkcję po krótkim testowaniu. Teraz program nie będzie się kompilował, dopóki nie usunę tych importów, a kilka minut później muszę ponownie zaimportować bibliotekę.

Robiłem ten proces wielokrotnie podczas tworzenia programu GAE.

Nacięcie
źródło
1
Nie jest dobrym pomysłem pozostawianie nieużywanych importów w kodzie, ale możesz po prostu tymczasowo je skomentować.
elithrar
73
Zgadzam się, że nie jest dobrym pomysłem pozostawianie nieużywanych importów, ale niepotrzebne marnowanie wysiłków programisty na robienie takich rzeczy, zwłaszcza że zdarza się to bardzo często podczas testowania czegoś. Głosy negatywne muszą dotyczyć mojego stosunku do GO przez tych fanów Go.
Nick
6
To funkcja, a nie błąd .
beatgammit
1
Usunięcie nieużywanego importu to dobra rzecz. Istnieje wiele przewodników stylistycznych, które wymagają, aby wszystkie ostrzeżenia były traktowane jako błędy, więc dodanie nowego ostrzeżenia jest ogólnie złym pomysłem. Być może flaga -dev może być możliwym kompromisem, ale var _ = <module>.Functiondziała dobrze i jest na tyle rzucająca się w oczy, że nie jest powszechną praktyką.
deft_code
1
Ponieważ ktoś dotyka odpowiedzi poniżej, zalecam albo użycie IDE, które zarządza importem (Gogland, LiteIDE itp. - jest ich kilka), albo goimportsjako krok w procesie budowania. Bez żadnego z nich szybko się starzeje.
Josef Grahn

Odpowiedzi:

40

Dodanie podkreślenia ( _) przed nazwą pakietu zignoruje nieużywany błąd importu.

Oto przykład, jak możesz go użyć:

import (
    "log"
    "database/sql"

    _ "github.com/go-sql-driver/mysql"
)

Aby zaimportować pakiet wyłącznie ze względu na jego skutki uboczne (inicjalizację), użyj pustego identyfikatora jako jawnej nazwy pakietu.

Zobacz więcej na https://golang.org/ref/spec#Import_declarations

Kwaśne 9
źródło
To jest poprawna odpowiedź. Oparty na specyfikacji GoLang Doc, jest przeznaczony do importowania pakietu wyłącznie ze względu na skutki uboczne (inicjalizacja). Dokument specyfikacji GoLang tutaj: golang.org/ref/spec#Import_declarations
Will
Po prostu fantastycznie. To powinno znajdować się na liście dziesięciu najważniejszych rzeczy, o których deweloperzy nowi w golang powinni wiedzieć. Dziękuję Ci!
JM Janzen
11
Niezbyt przydatne. Problem polega na tym, że jeśli później chcesz ponownie użyć importu, musisz usunąć plik _(w przeciwnym razie nie można się odwołać do pakietu, ponieważ nie ma on nazwy). Jeśli masz zamiar to zrobić, równie dobrze możesz to skomentować / odkomentować. var _ = ...Sztuczka nie ma tego problemu.
EM0
Jeśli dodasz podkreślenie do "fmt"w Gogland, automatycznie dodaje, "fmt"więc masz oba _"fmt"i "fmt", co czyni je bezużytecznymi w tym IDE
kramer65
26

Tutaj var _ = fmt.Printfsztuczka jest pomocna.

Volker
źródło
Uwielbiam to rozwiązanie. Jest wystarczająco brzydki, aby uczynić go niepożądanym, ale działa, więc jest tam, jeśli naprawdę tego potrzebujesz.
deft_code
3
Aby uzyskać więcej informacji, sprawdź ten link tip.golang.org/doc/effective_go.html#blank_unused
Deepak Singh Rawat
3
W tej chwili jest to pomocne, ale kiedy użyłem tej techniki, zwykle nie wracałem i później nie usuwałem nieużywanego pustego identyfikatora, powodując, że importy pozostały, gdy naprawdę nie zamierzałem ich używać na dłuższą metę. Użycie narzędzia takiego jak goimports rozwiązało prawdziwy problem i zapewnia, że ​​mój import jest zawsze minimalny i czysty.
mdwhatcott
Moim zdaniem nadal głupi hack, choć prawdopodobnie najbardziej efektywny.
Anthony
+1, ponieważ można to zrobić w dowolnym miejscu pliku , co normalnie byłoby okropnym pomysłem, ale jest naprawdę przydatne, aby uniknąć konieczności skakania po pliku, aby dostać się do importinstrukcji iz powrotem, gdy tylko próbujesz kompilować lub testować jakiś plik z kodem, który jest iteracyjnie uzupełniany.
mtraceur
22

Mam ten sam problem. Rozumiem powód, dla którego zaimplementowali język, aby uniemożliwić nieużywane importy i zmienne, ale osobiście uważam tę funkcję za irytującą podczas pisania mojego kodu. Aby to obejść, zmieniłem ustawienia mojego kompilatora, aby zezwolić na opcjonalne flagi zezwalające na nieużywane zmienne i importy w moim kodzie.

Jeśli jesteś zainteresowany, możesz to zobaczyć na https://github.com/dtnewman/modified_golang_compiler .

Teraz mogę po prostu uruchomić kod za pomocą polecenia, takiego jak go run -gcflags '-unused_pkgs' test.go i nie spowoduje to wyświetlenia tych błędów „nieużywanego importu”. Jeśli pominę te flagi, powróci do wartości domyślnej, która nie zezwala na nieużywane importy.

Wymagało to tylko kilku prostych zmian. Puryści Go prawdopodobnie nie będą zadowoleni z tych zmian, ponieważ jest dobry powód, aby nie zezwalać na nieużywane zmienne / importy, ale osobiście zgadzam się z Tobą, że ten problem sprawia, że ​​kodowanie w Go jest znacznie mniej przyjemne, dlatego wprowadziłem te zmiany w moim kompilator.

dtzvi
źródło
2
Zrobiłem to samo z wersją 1.6, jeśli jesteś zainteresowany, sprawdź tutaj: github.com/ronelliott/go/tree/release-branch.go1.6 UWAGA: niektóre testy zakończą się niepowodzeniem
Ron E
2
Uwielbiam pomysł, który za tym stoi. Widzę, że fork nadal jest w wersji 1.2, co czyni go bezużytecznym. Powinno to być zawarte w standardowym kompilatorze go, przynajmniej po to, aby go run main.godomyślnie wyłączać błędy, a go buildwłączać błędy. W ten sposób programowanie przy użyciu jest łatwe, go runa kiedy nadejdzie czas na kompilację do produkcji, nadal będziesz zmuszony wyczyścić kod.
kramer65
17

Użyj goimports . Jest to w zasadzie rozwidlenie gofmt, napisane przez Brada Fitzpatricka, a teraz zawarte w pakietach narzędzi go. Możesz skonfigurować swój edytor, aby uruchamiał go za każdym razem, gdy zapiszesz plik. Nigdy więcej nie będziesz musiał martwić się tym problemem.

mdwhatcott
źródło
5

Jeśli używasz fmtpakietu do ogólnego drukowania na konsoli podczas programowania i testowania, możesz znaleźć lepsze rozwiązanie w pakiecie dziennika .

OldCurmudgeon
źródło
5
Lub wbudowana funkcja, o printlnktórej ludzie zawsze zapominają.
MatrixFrog
2
@MatrixFrog Na dłuższą metę budowanie na tych funkcjach nie jest dobrym pomysłem, ponieważ z czasem mogą one zniknąć. Używanie dziennika jest dobrym pomysłem, ponieważ możesz je zachować i jest on częścią standardowej biblioteki i prawdopodobnie nie zostanie usunięty. Zobacz specyfikację, aby uzyskać szczegółowe informacje.
nemo
1
Wbudowany println?? To dla mnie nowość. Czy to nie jest udokumentowane? Nie mogę go nigdzie znaleźć.
Matt,
1
@nemo dobra uwaga. Są idealne, gdy chcesz coś szybko wydrukować, ale nie masz zamiaru tego sprawdzać. Prawdopodobnie nie warto ich używać w innym przypadku.
MatrixFrog
1
@MartinTournoij - Nie zgadzam się. To było rozwiązanie, które w końcu znalazłem, gdy miałem ten problem 5 lat temu, a przy 5+ pozytywnych opiniach wyraźnie pomogło innym. Byłem nowicjuszem korzystającym z fmtpakietu do logowania, nieświadomym, że istnieje gotowy pakiet do logowania.
OldCurmudgeon,
5

Służy if false { ... }do komentowania kodu. Kod w nawiasach klamrowych musi być poprawny składniowo, ale w przeciwnym razie może być kodem bezsensownym.

topskip
źródło
3
Bardziej niż poprawna składniowo, wszelkie zmienne, do których istnieją odniesienia (np. Foo.Bar) muszą istnieć itp.
Dragon
To nie jest zbyt czyste ani idiomatyczne. Jest powód, dla którego Go został zaprojektowany tak, jak był
Acidic9
1
Jest to fajna technika, gdy ktoś po prostu wypróbowuje różne rzeczy podczas tworzenia skryptu lub eksplorowania interfejsów API w Golang. Dziękuję topskip!
Jay Taylor
2

Wiele osób już skomentowało, podając ważne uzasadnienie, a ja również zgadzam się z intencją oryginalnego autora. Jednak Rob Pike wspomniał na różnych forach, że Go jest wynikiem uproszczenia procesów, których brakuje kilku innym głównym językom programowania lub które nie są łatwe do osiągnięcia. To semantyka języka Go, a także przyspieszenie kompilacji, jest wiele rzeczy, które są przyjmowane, co początkowo wydaje się nieefektywne.

Krótko mówiąc, nieużywane importy są traktowane jako błędy w Go, ponieważ blokuje program i spowalnia kompilację. Użycie importu dla efektu ubocznego (_) jest obejściem, jednak wydaje mi się to mylące, gdy istnieje mieszanka prawidłowych importów z efektami ubocznymi wraz z efektami ubocznymi importowanymi wyłącznie w celu debugowania / testowania, zwłaszcza gdy kod jest jest duży i istnieje szansa, aby zapomnieć i nie usunąć nieumyślnie, co może później zmylić innych inżynierów / recenzentów. Kiedyś komentowałem nieużywane, jednak popularne IDE, takie jak kod VS i Goland, mogą z goimportsłatwością używać, co całkiem dobrze wykonuje wstawianie i usuwanie importu. Więcej informacji można znaleźć w linku https://golang.org/doc/effective_go.html#blank_import

sbcharr
źródło
Dzięki za to! Sugerowałbym jawne skopiowanie i wklejenie wiersza kodu z adresu URL, który zamieściłeś w swojej odpowiedzi jako konkretny przykład importowania ze względu na efekt uboczny: import _ "net/http/pprof"
Dragon
1
Dzięki @Dragon za sugestię! Ponieważ jestem nowym współtwórcą, z pomocą ludzi takich jak Ty, moje posty szybko się poprawią.
sbcharr
-1

umieść to na swoim dokumencie i zapomnij o niewykorzystanych importach:

import (
    "bufio"
    "fmt"
    "os"
    "path/filepath"
)

var _, _, _, _ = fmt.Println, bufio.NewReader, os.Open, filepath.IsAbs
goen
źródło
1
Zamiast zmuszać kompilator do generowania martwego kodu, jeśli naprawdę chcesz to zrobić, użyj _zamiast tego zmiennych globalnych (np. Jeden pakiet w wierszu lub jeśli nalegasz, wszystkie razem, jak var _, _, _, _ = fmt.Println, bufio.NewReader, os.Open, filepath.IsAbs:). Ale nie rób tego, po prostu użyj goimports.
Dave C