“Beyan edilen ve kullanılmayan” can sıkıcı hatayı önleme


238

Ben Go öğreniyorum ama derlerken, herhangi bir değişken veya paketi kullanılmamış bırakmam gerektiğini biraz can sıkıcı hissediyorum.

Bu beni oldukça yavaşlatıyor. Örneğin, sadece yeni bir paket beyan etmek ve daha sonra kullanmayı planlamak veya sadece test etmek için bazı komutları bırakmak istedim. Ben her zaman hata alıyorum ve tüm bu kullanımları yorum gitmek gerekir.

Go'da bu tür çeklerden kaçınmanın bir yolu var mı?


1
Sizin için otomatik olarak ithalat eklemek / kaldırmak için goimports'u ( godoc.org/code.google.com/p/go.tools/cmd/goimports ) de kullanabilirsiniz .
elithrar


3
Hala derleyici seçeneği "Hata ayıklamaya yardımcı olmak için bir şey yorum yapmak istiyorum" iş akışı için yararlı olacağını hissediyorum.
RJFalconer

13
Bu özellik insanların zaman kaybetmek için harika bir yoldur lol, ne anlamı var? Ne zaman taahhüt / gemi kodu, tamam hiç kullanılmayan vars güzel, ama geliştirirken? Korkunç.
Alexander Mills

Bu 2020 ve hala (onlar bir derleyici bayrağı ile bile) bu sabit değil inanamıyorum. Go'da yaklaşık 5 yıl önce bir proje yaptım ve genel olarak dili beğendim, ancak sadece bu yüzden benim için kullanılamazdı. Kodlama şekli sürekli olarak yorum / uncommenting şeyler, bu yüzden Go bu "özellik" şeyler benim için iki kat daha fazla zaman yapar ... O zamandan beri bir neden duygusu geçip geçmediğini görmek için birkaç ayda bir kontrol ediyorum Go takımı ve şimdiye kadar hiç şans yok ... Berbat. Aksi takdirde harika bir dil ve daha fazla kullanmak isterdim, ama şu anda benim için kullanışlı değil.
Ruslan

Yanıtlar:


234

Bu hata, sizi daha iyi kod yazmaya zorlamak ve beyan ettiğiniz veya içe aktardığınız her şeyi kullandığınızdan emin olmak için burada. Başkaları tarafından yazılan kodu okumayı kolaylaştırır (beyan edilen tüm değişkenlerin her zaman kullanılacağından emin olabilirsiniz) ve olası bazı ölü kodlardan kaçının.

Ancak, bu hatayı gerçekten atlamak istiyorsanız, boş tanımlayıcıyı ( _) kullanabilirsiniz:

package main

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

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

olur

package main

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

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

Kostix tarafından aşağıdaki yorumlarda belirtildiği gibi, Go ekibinin resmi konumunu SSS'de bulabilirsiniz :

Kullanılmayan bir değişkenin varlığı bir hatayı gösterebilir, kullanılmayan ithalatlar ise derlemeyi yavaşlatır. Kod ağacınızda yeterince kullanılmamış ithalat biriktirdiğinizde işler çok yavaşlayabilir. Bu nedenlerle Go hiçbirine izin vermez.


90
Yine de, bu yorum yapmaktan çok farklı değil. Ve, bunun daha iyi kod için olduğunu anlıyorum, ancak kodumuzu test etmenin nedenini kontrol edip kodu bitirip temizlemeyi istedikten sonra tekrar açabilirsek daha iyi olur mu?
A-letubby

21
@kostix Şey .. sizi yavaşlatmayabilir, çünkü bir uzman olabilirsiniz ama bu benim ve kodlama şeklim. Sadece daha iyi bir yol olup olmadığını merak ediyorum. Neyse, SSS için teşekkürler! Bunu okuyarak, golang'ın bu şekilde yaptığı nedenleri tamamen anlayabiliyorum.
A-letubby

20
Bunu kapatmak için bir komut satırı argümanı var mı? Yoksa bu değiştirilemez bir özellik midir?
Ethan Bierlein

26
FWIW, başkalarının kodlarını okumakta zorlandım, ama kesinlikle kullanılmayan sembollerden dolayı değil. OTOH, bugün bu * #% $ golang "özelliği" ile başa çıkmak için yöntemleri araştıran bir saat kaybettim.
Torsten Bronger

24
Ne yazık ki bu cevap doğru - ama bu haklı değil. Kodu kontrol etmek ve basitçe yürütmek arasında bir fark dünyası var. Kodu kontrol ettiğimizde, bu tür bir hatayı yakalamak için linterleri kullanırız. Hızlı gelişim sırasında yürüttüğümüzde aynı standartlara sahip değiliz. Bir derleyiciyi bir linter ile karıştırmak affedilemez. Google'ın içindeki stil polisi bile bu hatayı yapmaz.
Travis Wilson

29

Bunun için basit bir "boş işlev" kullanabilirsiniz, örneğin:

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

Hangi gibi kullanabilirsiniz:

package main

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

    Use(a, b, c)
}

Bunun için bir paket de var, böylece Useişlevi her seferinde tanımlamanız gerekmez :

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

func main() {
  // [..]

  xulu.Use(a, b, c)
}

29

SSS'ye göre :

Bazıları bu kontrolleri kapatmak veya en azından uyarılara indirmek için bir derleyici seçeneği istedi. Ancak böyle bir seçenek eklenmemiştir, çünkü derleyici seçenekleri dilin anlambilimini etkilememelidir ve Go derleyicisi uyarıları bildirmediğinden, yalnızca derlemeyi engelleyen hatalardır.

Uyarı almamanın iki nedeni vardır. İlk olarak, şikayet etmeye değerse, kodda düzeltmeye değer. (Ve düzeltmeye değmezse, bahsetmeye değmez.) İkincisi, derleyicinin uyarı oluşturması, uygulamayı derleme gürültülü hale getirebilecek zayıf durumlar hakkında uyarmaya ve düzeltilmesi gereken gerçek hataları maskelemeye teşvik eder.

Buna girmeye değmeyen çeşitli nedenlerle buna katılmama gerek yok. Budur ve yakın gelecekte değişmesi muhtemel değildir.

Paketler için, goimportseksik paketleri otomatik olarak ekleyen ve kullanılmayanları kaldıran bir araç vardır. Örneğin:

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

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

Bunu herhangi bir yarım yönlü iyi editörden çalıştırabilmelisiniz - örneğin Vim için:

:!goimports -w %

goimportsSayfa listeleri diğer editörler için bazı komutlar ve genellikle bunu ayarladığınızda diske tampon tasarrufu otomatik olarak çalıştırılmak üzere.

Not goimportsda çalışacaktır gofmt.


Daha önce de belirtildiği gibi, değişkenler için en kolay yol (geçici olarak) bunları atamaktır _:

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

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

_, _ = tasty, horrible

9

Şimdiye kadar bahsedilmeyen bir açı, kodu düzenlemek için kullanılan araç setleridir.

Kullanımı Visual Studio kod adlı Uzantısı ile birlikte lukehoban denilen Gosizin için bazı oto-büyü yapacağız. Git uzantısı otomatik olarak çalışır gofmt, golintvs, ve kaldırır ve ekler importgirdileri . Yani en azından bu bölüm artık otomatik.

Sorunun çözümünün% 100'ünü değil, ancak yeterince yararlı olduğunu kabul edeceğim.


8

Diğerlerinin bunu anlamakta zorlanmaları durumunda, bunu çok basit bir şekilde açıklamaya yardımcı olabileceğini düşünüyorum. Kullanmadığınız bir değişkeniniz varsa, örneğin çağrıyı yorumladığınız bir işlev (ortak bir kullanım örneği):

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

İşleve artık kullanılmaması için işe yaramaz / boş bir değişken atayabilirsiniz :

myFn := func () { }
_ = myFn
// myFn()
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.