Golang kullanılmayan içe aktarma hatası nasıl devre dışı bırakılır


101

Go, varsayılan olarak kullanılmayan içe aktarmayı hata olarak değerlendirerek sizi içe aktarmayı silmeye zorlar. Bu davranışı değiştirmek için bir umut olup olmadığını bilmek istiyorum, örneğin bunu uyarıya düşürmek.

Bu sorunu son derece can sıkıcı buluyorum ve Go'da kodlamanın tadını çıkarmamı engelliyor.

Örneğin, bir segmenti / işlevi devre dışı bırakarak bazı kodları test ediyordum. Kitaplıktaki bazı işlevler artık kullanılmıyor (örneğin fmt, hatalar, her neyse), ancak küçük bir testten sonra işlevi yeniden etkinleştirmem gerekecek. Şimdi bu içe aktarmaları kaldırmadığım sürece program derlenmeyecek ve birkaç dakika sonra kütüphaneyi yeniden içe aktarmam gerekiyor.

Bir GAE programı geliştirirken bu işlemi tekrar tekrar yapıyordum.


1
Kullanılmayan içe aktarmaları kodunuzda bırakmak iyi bir fikir değildir, ancak bunları geçici olarak yorumlayabilirsiniz.
elithrar

76
Kullanılmayan ithalatları bırakmanın iyi bir fikir olmadığını kabul ediyorum, ancak programcının bu gibi şeyler yapma çabasını gereksiz yere boşa harcamak kötü bir fikir, özellikle bu, bir şeyi test ederken çok sık oluyor. Bu olumsuz oylar, Go hayranlarının GO'ya karşı tavrım için olmalı.
Nick

6
Bu bir özellik, hata değil .
beatgammit

1
Kullanılmayan ithalatı kaldırmak iyi bir şeydir. Tüm uyarıların hata olarak değerlendirilmesini gerektiren birçok stil kılavuzu vardır, bu nedenle yeni bir uyarı eklemek genellikle kötü bir fikirdir. Belki bir -dev bayrağı olası bir uzlaşma olabilir, ancak var _ = <module>.Functionişler iyi ve ortak bir uygulama olmasını engelleyecek kadar dikkat çekicidir .
deft_code

1
Birisi aşağıdaki cevaplara değindiği için, ithalatı yöneten bir IDE kullanmanızı (Gogland, LiteIDE, vb. - birkaç tane var) veya goimportsoluşturma sürecinizde bir adım atmanızı öneririm . Bunların hiçbiri olmadan çok hızlı eskimektedir.
Josef Grahn

Yanıtlar:


40

_Bir paket adından önce alt çizgi ( ) eklemek , kullanılmayan içe aktarma hatasını yok sayacaktır.

İşte onu nasıl kullanabileceğinize dair bir örnek:

import (
    "log"
    "database/sql"

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

Bir paketi yalnızca yan etkileri (başlatma) için içe aktarmak için, açık paket adı olarak boş tanımlayıcıyı kullanın.

Https://golang.org/ref/spec#Import_declarations adresinde daha fazlasını görüntüleyin


Bu doğru cevap. GoLang spesifikasyon Belgesine göre, bir paketi yalnızca yan etkiler (başlatma) için içe aktarmak için kullanılması amaçlanmıştır. : GoLang Spec Doc burada golang.org/ref/spec#Import_declarations
Will

Tek kelimeyle harika. Bu, golang için yeni olan geliştiricilerin bilmesi gereken ilk on şey listesinde olmalıdır. Teşekkür ederim!
JM Janzen

13
Pek kullanışlı değil. Bununla ilgili sorun, içe aktarmayı daha sonra tekrar kullanmak isterseniz, kaldırmanız gerektiğidir _(aksi takdirde, adı olmadığı için pakete referans verilemez). Eğer bunu yapacaksan, sadece yorum yapabilir / yorumunu kaldırabilirsin. var _ = ...Hüner bu sorunu yoktur.
EM0

Size çizgi eklerseniz "fmt"Gogland içinde, otomatik olarak ekler "fmt"her ikisine de sahip olacak şekilde _"fmt"ve "fmt"bu IDE içinde hangi yararsız render,
kramer65

26

var _ = fmt.PrintfHüner burada yararlıdır.


Bu çözümü seviyorum. İstenmeyen hale getirecek kadar çirkin, ama işe yarıyor, bu yüzden gerçekten ihtiyacınız varsa orada.
deft_code

3
Daha fazla ayrıntı için lütfen bu bağlantıyı kontrol edin tip.golang.org/doc/effective_go.html#blank_unused
Deepak Singh Rawat

3
Şu anda yardımcı oluyor, ancak bu tekniği kullandığımda daha sonra geri dönüp kullanılmayan boş tanımlayıcıyı silme eğilimindeydim, bu da uzun vadede onları gerçekten kullanmak istemediğimde içe aktarmaların takılıp kalmasına neden oldu. Goimports gibi bir araç kullanmak gerçek sorunu çözdü ve ithalatımın her zaman minimum ve temiz olmasını sağlıyor.
mdwhatcott

Bence hala aptalca bir hack, muhtemelen yapılacak en etkili şey.
Anthony

+1 çünkü bu , dosyanın herhangi bir yerinde yapılabilir , bu normalde berbat bir fikir olurdu, ancak importifadeye ulaşmak için dosyada zıplamaktan ve sadece derlemeye veya test etmeye çalışırken geri dönmek zorunda kalmamak için gerçekten yararlı yinelemeli olarak incelediğiniz bazı kod dosyaları .
mtraceur

22

Bende de aynı sorun var. Kullanılmayan içe aktarmalara ve değişkenlere izin vermemek için dili neden uyguladıklarının gerekçesini anlıyorum, ancak kişisel olarak bu özelliği kodumu yazarken can sıkıcı buluyorum. Bunu aşmak için, derleyicimin etrafını değiştirerek kodumda kullanılmayan değişkenlere ve içe aktarmalara izin vermek için isteğe bağlı bayraklara izin verdim.

Eğer ilgileniyorsanız, bunu şurada görebilirsiniz: https://github.com/dtnewman/modified_golang_compiler adresinde .

Artık go run -gcflags '-unused_pkgs' test.go gibi bir komutla kod çalıştırabilirim. ve bu "kullanılmayan içe aktarma" hatalarını . Bu bayrakları dışarıda bırakırsam, kullanılmayan içe aktarmalara izin vermeme varsayılanına geri döner.

Bunu yapmak yalnızca birkaç basit değişiklik gerektirdi. Kullanılmayan değişkenlere / içe aktarmalara izin vermemek için iyi bir neden olduğundan, Go sadeliği büyük olasılıkla bu değişikliklerden memnun olmayacaktır, ancak kişisel olarak bu sorunun Go'da kodlamayı çok daha az eğlenceli hale getirdiği konusunda sizinle aynı fikirdeyim, bu yüzden bu değişiklikleri benim derleyici.


2
1.6 sürümüyle de aynısını yaptım, ilgileniyorsanız burayı kontrol edin: github.com/ronelliott/go/tree/release-branch.go1.6 NOT: bazı testler başarısız olacak
Ron E

2
Bunun arkasındaki fikri seviyorum. Fork'unuzun hala 1.2 sürümünde olduğunu görüyorum, bu da onu işe yaramaz hale getiriyor. Bu, en azından go run main.govarsayılan olarak hataları devre dışı bırakacak ve hataları etkinleştirecek şekilde standart go derleyicisine dahil edilmelidir go build. Bu şekilde kullanarak geliştirmek kolaydır go runve üretim için geliştirme zamanı geldiğinde, yine de kodunuzu temizlemeye zorlanırsınız.
kramer65

18

Goimportları kullanın . Temelde gofmtBrad Fitzpatrick tarafından yazılmış bir çataldır ve şimdi go araçları paketlerine dahil edilmiştir. Düzenleyicinizi, bir dosyayı her kaydettiğinizde çalıştıracak şekilde yapılandırabilirsiniz. Bir daha asla bu sorun için endişelenmenize gerek kalmayacak.


Bu nesnel olarak doğru cevaptır. 1. Go içe aktarmaları kullanın 2. Düzenleyicinizi kaydetme üzerinde biçimlendirmek için yapılandırın 3. Bu kabusta sonsuza kadar devam edin.
Simon Merrick

5

fmtPaketi geliştirirken ve test ederken konsola genel yazdırma için kullanıyorsanız , günlük paketinde daha iyi bir çözüm bulabilirsiniz .


5
Veya printlninsanların her zaman unutmuş gibi göründüğü yerleşik işlev .
MatrixFrog

2
@MatrixFrog Uzun vadede, zamanla yok olabileceklerinden bu işlevlerin üzerine inşa etmek iyi bir fikir değildir. Günlük kullanmak, bunları saklayabileceğiniz ve standart kitaplığın bir parçası olduğu ve kaldırılamayacağı için iyi bir fikirdir. Ayrıntılar için teknik özelliklere bakın.
nemo

1
Yerleşik printlnmi? Bu benim için bir haber. Belgelenmemiş mi? Onu hiç bir yerde bulamıyorum.
Mat

1
@nemo iyi nokta. Bir şeyi hızlı bir şekilde tek seferde yazdırmanız gerektiğinde mükemmeldirler, ancak gerçekten kontrol etme niyetinde değilsiniz. Muhtemelen bunları başka bir durumda kullanmak iyi değil.
MatrixFrog

1
@MartinTournoij - Katılmıyorum. Bu sorunu 5 yıl önce yaşadığımda bulduğum çözüm buydu ve 5'ten fazla ek oyla başkalarına açıkça yardımcı oldu. fmtGünlük kaydı için paketi kullanan bir acemiydim , hazır bir günlük kaydı paketi olduğunun farkında değildim.
OldCurmudgeon

5

Bazı kodları yorumlamakif false { ... } için kullanın . Küme parantezleri içindeki kod sözdizimsel olarak doğru olmalıdır, ancak aksi takdirde anlamsız kod olabilir.


3
Sözdizimsel olarak doğru olmanın ötesinde, başvurulan herhangi bir değişken (örn. Foo.Bar) mevcut olmalıdır, vb.
Dragon

Bu çok temiz ya da deyimsel değil. Go'nun bu şekilde tasarlanmasının bir nedeni var
Acidic9

1
Bu, Golang'da bir komut dosyası geliştirirken veya API'leri keşfederken basitçe bir şeyler denediğinde güzel bir tekniktir. Teşekkür ederim atla!
Jay Taylor

2

Birçok kişi zaten geçerli gerekçelerle yorum yaptı ve ben de orijinal yazarın niyetini kabul ediyorum. Bununla birlikte, Rob Pike, farklı forumlarda Go'nun birkaç diğer ana programlama dilinin eksik olduğu veya ulaşması kolay olmayan süreçlerin basitleştirilmesinin bir sonucu olduğunu belirtti. Go'nun dil anlambilimidir ve derlemeyi daha hızlı hale getirmenin yanı sıra, başlangıçta verimsiz görünen birçok şey benimsenmiştir.

Kısaca, kullanılmayan içe aktarmalar Go'da programı kararttığı ve derlemeyi yavaşlattığı için hata olarak kabul edilir. Yan etki (_) için içe aktarmanın kullanılması geçici bir çözümdür, ancak, yan etkilerle birlikte geçerli içe aktarmaların bir karışımının yanı sıra yalnızca hata ayıklama / test amacıyla içe aktarılan yan etkiler olduğunda, özellikle kod tabanı şu durumlarda kafa karıştırıcı buluyorum: büyüktür ve daha sonra diğer mühendislerin / gözden geçirenlerin kafasını karıştırabilecek şekilde unutma ve istemeden silmeme şansı vardır. Kullanılmayanları yorumluyordum, ancak VS kodu ve Goland gibi popüler IDE'ler goimportskolayca kullanabilir , bu da ithalatların eklenmesini ve silinmesini oldukça iyi yapar. Daha fazla bilgi için lütfen bağlantıya bakın, https://golang.org/doc/effective_go.html#blank_import


Bunun için teşekkürler! Yan etki için içe aktarmanın somut bir örneği olarak yanıtınıza gönderdiğiniz URL'deki kod satırını açıkça kopyalayıp yapıştırmanızı öneririm: import _ "net/http/pprof"
Dragon

1
Öneriniz için teşekkürler @ Dragon! Yeni bir katkıda bulunduğum için, sizin gibi insanların yardımıyla, gönderilerimle hızla daha iyi hale geleceğim.
sbcharr

-1

bunu belgenizin üstüne koyun ve kullanılmayan ithalatı unutun:

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

var _, _, _, _ = fmt.Println, bufio.NewReader, os.Open, filepath.IsAbs

1
Bunun yerine derleyici ölü kodu oluşturmak yapma eğer gerçekten bunu yapmak istedim, kullanmak _genel değişkenleri yerine (örneğin ya bir satıra veya eğer ısrar paketi gibi hep birlikte: var _, _, _, _ = fmt.Println, bufio.NewReader, os.Open, filepath.IsAbs). Ama bunu yapma, sadece kullan goimports.
Dave C
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.