Bagaimana cara menghindari kesalahan yang mengganggu "dinyatakan dan tidak digunakan"

238

Saya sedang mempelajari Go, tetapi saya merasa agak menjengkelkan bahwa ketika mengkompilasi, saya seharusnya tidak meninggalkan variabel atau paket yang tidak digunakan.

Ini benar-benar memperlambat saya. Sebagai contoh, saya hanya ingin mendeklarasikan paket baru dan berencana untuk menggunakannya nanti atau hanya membatalkan perintah untuk menguji. Saya selalu mendapatkan kesalahan dan perlu mengomentari semua penggunaan itu.

Apakah ada cara untuk menghindari jenis check in Go ini?

A-letubby
sumber
1
Anda juga dapat menggunakan goimport ( godoc.org/code.google.com/p/go.tools/cmd/goimports ) untuk secara otomatis menambah / menghapus impor untuk Anda.
elithrar
3
Saya masih merasa opsi kompiler akan berguna untuk alur kerja "Saya ingin mengomentari sesuatu untuk membantu debug".
RJFalconer
13
Fitur ini adalah cara terbaik untuk membuang waktu orang, apa gunanya? Saat Anda mengkomit / mengirimkan kode, ok tidak ada vars yang tidak digunakan itu bagus, tetapi ketika mengembangkannya? Mengerikan.
Alexander Mills
Ini tahun 2020 dan saya tidak percaya mereka masih belum memperbaikinya (bahkan dengan flag compiler). Saya melakukan proyek di Go sekitar 5 tahun yang lalu dan secara keseluruhan menyukai bahasa itu tetapi itu tidak dapat digunakan untuk saya hanya karena ini. Cara saya kode saya terus-menerus berkomentar / tidak berkomentar hal-hal, jadi ini "fitur" di Go membuat semuanya butuh waktu dua kali lipat bagi saya ... Saya telah memeriksa kembali setiap beberapa bulan sejak itu untuk melihat apakah rasa alasan telah diambil alih tim Go, dan sejauh ini tidak berhasil ... Sucks. Itu bahasa yang bagus dan saya ingin menggunakannya lebih banyak, tetapi saat ini tidak bisa digunakan untuk saya.
Ruslan

Jawaban:

235

Kesalahan itu ada di sini untuk memaksa Anda menulis kode yang lebih baik, dan pastikan untuk menggunakan semua yang Anda deklarasikan atau impor. Ini membuatnya lebih mudah untuk membaca kode yang ditulis oleh orang lain (Anda selalu yakin bahwa semua variabel yang dideklarasikan akan digunakan), dan menghindari beberapa kode mati yang mungkin.

Tetapi, jika Anda benar-benar ingin melewati kesalahan ini, Anda dapat menggunakan pengidentifikasi kosong ( _):

package main

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

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

menjadi

package main

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

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

Seperti yang dikatakan oleh kostix dalam komentar di bawah, Anda dapat menemukan posisi resmi tim Go di FAQ :

Kehadiran variabel yang tidak digunakan dapat menunjukkan bug, sementara impor yang tidak digunakan hanya memperlambat kompilasi. Akumulasi cukup impor yang tidak terpakai di pohon kode Anda dan banyak hal bisa sangat lambat. Karena alasan ini, Go tidak mengizinkan keduanya.

Florent Bayle
sumber
90
Namun, ini tidak jauh berbeda dengan berkomentar. Dan, saya mengerti bahwa ini untuk kode yang lebih baik tetapi apakah akan lebih baik jika kita dapat menutup pemeriksaan mengapa menguji kode kita dan kemudian membuka pemeriksaan ini lagi setelah kita ingin menyelesaikan kode dan membuatnya bersih?
A-letubby
21
@kostix Yah .. itu mungkin tidak memperlambat Anda karena Anda mungkin menjadi ahli tetapi bagi saya dan cara saya coding. Saya hanya ingin tahu apakah ada cara yang lebih baik. Tapi bagaimanapun, terima kasih untuk FAQ! Dengan membaca ini, saya benar-benar bisa mengerti untuk alasan apa golang melakukan cara ini.
A-letubby
20
Apakah ada argumen baris perintah untuk mematikan ini? Atau apakah ini fitur yang tidak dapat diubah?
Ethan Bierlein
26
FWIW, saya pernah mengalami kesulitan membaca kode orang lain, tapi jelas bukan karena simbol yang tidak digunakan. OTOH, saya kehilangan satu jam hari ini menyelidiki metode untuk menangani "fitur" golang * #% $ ini.
Torsten Bronger
24
Sayangnya jawaban ini benar - tetapi itu tidak membenarkannya. Ada perbedaan besar antara memeriksa kode dan hanya menjalankannya. Ketika kami memeriksa kode, kami menggunakan linter untuk menangkap kesalahan semacam ini. Ketika kami mengeksekusi selama pengembangan cepat, kami tidak memiliki standar yang sama. Tidak termaafkan untuk mengacaukan kompiler dengan linter. Bahkan polisi gaya di Google tidak melakukan kesalahan itu.
Travis Wilson
29

Anda dapat menggunakan "fungsi null" sederhana untuk ini, misalnya:

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

Yang bisa Anda gunakan seperti ini:

package main

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

    Use(a, b, c)
}

Ada juga paket untuk ini sehingga Anda tidak harus mendefinisikan Usefungsi setiap waktu:

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

func main() {
  // [..]

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

Menurut FAQ :

Beberapa telah meminta opsi kompiler untuk menonaktifkan cek tersebut atau setidaknya menguranginya menjadi peringatan. Opsi seperti itu belum ditambahkan, karena opsi kompiler seharusnya tidak mempengaruhi semantik bahasa dan karena kompilator Go tidak melaporkan peringatan, hanya kesalahan yang mencegah kompilasi.

Ada dua alasan mengapa tidak ada peringatan. Pertama, jika layak dikeluhkan, ada baiknya Anda memperbaiki kode. (Dan jika itu tidak layak diperbaiki, itu tidak layak disebutkan.) Kedua, memiliki kompiler menghasilkan peringatan mendorong implementasi untuk memperingatkan tentang kasus-kasus lemah yang dapat membuat kompilasi berisik, menutupi kesalahan nyata yang harus diperbaiki.

Saya tidak perlu setuju dengan ini karena berbagai alasan yang tidak layak untuk dibahas. Ini adalah apa adanya, dan itu tidak akan berubah dalam waktu dekat.

Untuk paket, ada goimportsalat yang secara otomatis menambahkan paket yang hilang dan menghapus yang tidak digunakan. Sebagai contoh:

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

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

Anda harus dapat menjalankan ini dari editor setengah jalan yang layak - misalnya untuk Vim:

:!goimports -w %

The goimportshalaman daftar beberapa perintah untuk editor lain, dan Anda biasanya mengaturnya untuk dijalankan secara otomatis ketika Anda menyimpan buffer ke disk.

Catatan yang goimportsjuga akan berjalan gofmt.


Seperti yang telah disebutkan, untuk variabel cara termudah adalah dengan (sementara) menugaskan mereka ke _:

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

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

_, _ = tasty, horrible
Martin Tournoij
sumber
9

Satu sudut yang sejauh ini tidak disebutkan adalah set alat yang digunakan untuk mengedit kode.

Menggunakan Visual Studio Code bersama dengan Extension dari lukehoban disebut Goakan melakukan beberapa sihir otomatis untuk Anda. Ekstensi Go secara otomatis berjalan gofmt, golintdll, dan menghapus serta menambah importentri . Jadi setidaknya bagian itu sekarang otomatis.

Saya akui itu bukan 100% dari solusi untuk pertanyaan itu, tetapi betapapun cukup berguna.

miltonb
sumber
8

Seandainya ada orang lain yang kesulitan memahami hal ini, saya pikir mungkin akan membantu menjelaskannya dengan cara yang sangat mudah. Jika Anda memiliki variabel yang tidak Anda gunakan, misalnya fungsi yang telah Anda komentari permohonannya (kasus penggunaan umum):

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

Anda dapat menetapkan variabel tidak berguna / kosong ke fungsi sehingga tidak lagi tidak digunakan :

myFn := func () { }
_ = myFn
// myFn()
pemohon maks
sumber