Variabel dan Inferensi Tipe

Deklarasi var, deklarasi pendek :=, dan zero value.

Daftar isi

Topik ini membahas dua cara mendeklarasikan variabel di Go, yaitu kata kunci var dan deklarasi pendek :=, beserta konsep zero value yang menyertainya. Keduanya menetapkan nama, tipe, dan nilai awal sebuah variabel, tetapi tempat pemakaiannya berbeda. Setelah membaca topik ini, pemilihan antara var dan := dapat dilakukan secara sadar, dan perilaku variabel yang dideklarasikan tanpa nilai awal dapat diprediksi.

Deklarasi dengan kata kunci var#

Kata kunci var mendeklarasikan variabel beserta tipenya secara eksplisit. Bentuk paling sederhananya adalah var nama tipe, yang membuat variabel tanpa nilai awal, sedangkan bentuk var nama tipe = nilai sekaligus mengisinya. Program berikut mendeklarasikan empat variabel dengan tipe berbeda, semuanya tanpa nilai awal, lalu mencetaknya:

go zero-value.go
package main

import "fmt"

func main() {
	var kecepatan int
	var jarak float64
	var nama string
	var aktif bool

	fmt.Println("kecepatan:", kecepatan)
	fmt.Println("jarak    :", jarak)
	fmt.Println("nama     :", nama)
	fmt.Println("aktif    :", aktif)
}
text Keluaran
kecepatan: 0
jarak    : 0
nama     :
aktif    : false

Tidak ada variabel yang berisi nilai acak atau sisa memori. Go menjamin setiap variabel yang dideklarasikan tanpa nilai awal langsung berisi zero value, yaitu nilai nol yang ditetapkan untuk tipe masing-masing. Jaminan ini membuat perilaku program deterministik sejak baris pertama, karena pembacaan variabel yang lupa diisi tetap menghasilkan nilai yang terdefinisi, bukan keadaan yang tidak dapat diprediksi.

Bentuk lain dari var melengkapi kebutuhan penulisan. Pernyataan var a, b int mendeklarasikan dua variabel sejenis dalam satu baris, sedangkan var suhu = 25 menyebut nilai tanpa tipe, sehingga tipe suhu disimpulkan dari nilai itu. Mekanisme penyimpulan ini sama dengan deklarasi pendek pada bagian berikut. Deklarasi var di tingkat package dapat dipakai oleh seluruh berkas dalam package yang sama, sehingga menjadi tempat yang alami bagi keadaan yang dimiliki bersama.

Zero value untuk setiap tipe#

Zero value ditetapkan per tipe, bukan per variabel, sehingga nilainya selalu sama untuk tipe yang sama. Tabel berikut memuat nilai nol untuk tipe-tipe dasar pada topik ini.

TipeZero valueKeterangan
int0Bilangan bulat bernilai nol
float640Dicetak sebagai 0, bukan 0.0
string""String kosong, tanpa satu byte pun
boolfalseNilai logika palsu

Untuk tipe kumpulan seperti slice, peta, dan pointer, zero value-nya adalah nil, yaitu penanda bahwa variabel belum menunjuk ke nilai apa pun. Pembahasan lengkapnya mengikuti pada modul tipe komposit. Pola ini menjadi dasar satu prinsip desain Go yang menonjol, yaitu nilai nol yang memang layak dipakai, sehingga banyak tipe dapat digunakan segera setelah dideklarasikan tanpa pemanggilan constructor.

Deklarasi pendek dengan :=#

Di dalam badan fungsi, Go menyediakan deklarasi pendek nama := nilai yang mendeklarasikan variabel sekaligus mengisinya tanpa menyebut tipe. Tipe variabel disimpulkan dari nilai di sebelah kanan, mekanisme yang disebut type inference atau inferensi tipe. Program berikut memperlihatkan hasil penyimpulan tersebut dengan verb %T pada fmt.Printf, yang mencetak nama tipe operandnya:

go inferensi.go
package main

import "fmt"

func main() {
	jarak := 42
	suhu := 36.5
	nama := "Celsius"
	aktif := true

	fmt.Printf("jarak  bertipe %T\n", jarak)
	fmt.Printf("suhu   bertipe %T\n", suhu)
	fmt.Printf("nama   bertipe %T\n", nama)
	fmt.Printf("aktif  bertipe %T\n", aktif)
}
text Keluaran
jarak  bertipe int
suhu   bertipe float64
nama   bertipe string
aktif  bertipe bool

Bilangan bulat 42 disimpulkan sebagai int, sedangkan bilangan dengan titik desimal 36.5 disimpulkan sebagai float64. Inferensi bukan pengetikan dinamis, melainkan singkatan penulisan, karena tipe yang disimpulkan tetap mengikat variabel seumur hidupnya. Variabel jarak bertipe int selamanya, dan pemberian nilai pecahan padanya menjadi error kompilasi.

Deklarasi pendek hanya berlaku di dalam fungsi, sedangkan deklarasi di luar fungsi, misalnya variabel tingkat package, wajib memakai var atau const. Alasannya struktural, yaitu deklarasi tingkat package dieksekusi sebelum fungsi mana pun berjalan, sehingga bentuk pernyataannya dibuat seragam dan mudah dikenali.

Kapan memakai var dan kapan memakai :=#

Keduanya menghasilkan variabel yang identik, sehingga pilihannya merupakan persoalan keterbacaan. Pedoman yang lazim diikuti komunitas Go adalah sebagai berikut.

  • Gunakan := untuk mayoritas deklarasi di dalam fungsi, karena lebih ringkas dan tipe terlihat dari nilainya.
  • Gunakan var tanpa nilai awal untuk menegaskan bahwa zero value memang diinginkan, misalnya var total int sebelum perulangan penghitungan.
  • Gunakan var dengan tipe eksplisit apabila tipe yang disimpulkan tidak diinginkan, misalnya var jarak float64 = 42 agar bilangan bulat diperlakukan sebagai pecahan.
  • Deklarasi tingkat package selalu memakai var atau const.

Butir ketiga patut dicontohkan karena paling sering mencegah masalah. Deklarasi jarak := 42 menyimpulkan int, sedangkan rumus yang membutuhkan pecahan menuntut float64. Menulis var jarak float64 = 42 menyatakan maksud itu sekali di awal, sehingga operasi berikutnya tidak perlu konversi berulang. Pemilihan eksplisit semacam ini juga berlaku ketika tipe yang diinginkan bukan tipe bawaan inferensi, misalnya int64 pada kode yang sensitif terhadap ukuran tipe.

Kesalahan umum#

Kesalahan pertama adalah mendeklarasikan variabel tanpa pernah memakainya. Go menolaknya pada saat kompilasi, bukan memberi peringatan belakangan, karena variabel yang tidak terpakai hampir selalu menandakan kelalaian logika. Potongan berikut gagal dikompilasi dengan pesan declared and not used: y.

go
// tidak-dijalankan
x := 10
y := 20
fmt.Println(x) // y tidak pernah dipakai, sehingga kompilasi gagal

Kesalahan kedua adalah mengulang deklarasi pendek untuk variabel yang semuanya sudah ada. Bentuk := menuntut minimal satu variabel baru di sebelah kirinya, sehingga baris kedua pada potongan berikut gagal dengan pesan no new variables on left side of :=.

go
// tidak-dijalankan
a, b := 1, 2
a, b := 3, 4 // tidak ada variabel baru, sehingga kompilasi gagal

Perbaikannya bergantung pada maksud. Apabila kedua variabel hanya ingin diberi nilai baru, gunakan operator penugasan biasa =. Apabila variabelnya memang belum ada, deklarasikan dengan var atau tambahkan variabel baru pada bentuk := yang pertama.

Ringkasan#

  • var nama tipe mendeklarasikan variabel dengan zero value, sedangkan nama := nilai mendeklarasikan sekaligus mengisi di dalam fungsi.
  • Zero value ditetapkan per tipe, yaitu 0 untuk bilangan, "" untuk string, false untuk bool, dan nil untuk tipe kumpulan.
  • Inferensi tipe adalah singkatan penulisan, bukan pengetikan dinamis, karena tipe yang disimpulkan tetap mengikat variabel.
  • Deklarasi pendek := hanya berlaku di dalam fungsi dan menuntut minimal satu variabel baru di sebelah kiri.

Referensi#