11. Variabel dan tipe

Bab 07 menulis teks langsung di dalam panggilan fmt.Println. Cara itu bisa dipakai, tapi informasi yang dibutuhkan di lebih dari satu tempat harus diketik ulang setiap kali. Variabel mengatasi hal itu. Variabel adalah nama yang mewakili sebuah nilai, jadi kamu menulis nilainya sekali dan memakainya berulang kali.

Bab 04 dan Bab 10 sudah menampilkan := dan = secara singkat. Bab ini menjelaskannya dengan lengkap. Seperti sebelumnya, contoh pendek hanya menampilkan baris yang masuk ke dalam main.

Mendeklarasikan variabel

Bentuk deklarasi variabel yang paling umum di Go:

name := "Keiko"
fmt.Println("Hello, " + name)

Ada dua hal yang terjadi di baris pertama:

  • name adalah nama variabelnya. Kamu yang memilihnya.
  • := mendeklarasikan variabel baru dan menaruh nilai di sebelah kanan ke dalamnya. Tanda ini tidak berarti "sama dengan" seperti = dalam matematika.

Sekarang name mewakili string "Keiko", jadi baris kedua mencetak Hello, Keiko.

Go punya cara yang lebih panjang untuk menulis deklarasi yang sama, dengan kata kunci var dan tipe yang ditulis lengkap:

var name string = "Keiko"
fmt.Println(name)

Keduanya membuat variabel yang sama. Kebanyakan kode Go memakai := kalau sudah ada nilai awal, dan var kalau belum, seperti yang akan kamu lihat di bawah.

:= hanya bisa dipakai di dalam fungsi. Di luar fungsi, Go berhenti dengan syntax error: non-declaration statement outside function body. Kamu akan mempelajari fungsi di Bab 21. Untuk sekarang, semua variabelmu berada di dalam main.

Mengubah variabel

Nilai variabel bisa berubah. Gunakan = biasa, yang disebut assignment (penugasan):

score := 0
fmt.Println(score) // mencetak 0
score = 50
fmt.Println(score) // mencetak 50

:= membuat variabel baru dan = mengubah variabel yang sudah ada. Kalau tertukar, masing-masing menghasilkan error. Menulis score := 50 ketika score sudah ada menghasilkan:

no new variables on left side of :=

Menulis score = 50 ketika score belum ada menghasilkan:

undefined: score

Buka exercises/11/01-variables.go. Ubah nilai awal score dan jalankan file-nya. fmt.Println yang pertama seharusnya berubah. Yang kedua tetap mencetak 50. Mengapa?

Tipe

Di Go setiap nilai punya tipe, begitu juga setiap variabel. Empat tipe yang kamu butuhkan sekarang:

  • string — teks, ditulis di antara tanda kutip: "hello", "a", "" (string kosong).
  • int — bilangan bulat tanpa titik desimal: 0, -7, 42.
  • float64 — bilangan dengan titik desimal: 3.14, 0.5, -1.0.
  • bool — tepat dua nilai: true dan false. Tanpa tanda kutip, dan semuanya huruf kecil. True dengan huruf kapital menghasilkan error undefined: True.

Ketika kamu menulis :=, Go menentukan tipenya dari nilainya, jadi level := 7 membuat sebuah int.

fmt.Printf punya penanda yang mencetak tipe sebuah nilai: %T.

fmt.Printf("%T\n", "hello") // string
fmt.Printf("%T\n", 7)       // int
fmt.Printf("%T\n", 3.14)    // float64
fmt.Printf("%T\n", true)    // bool

Ini adalah exercises/11/02-types.go.

Nama float64 berasal dari "floating point", cara komputer menyimpan bilangan desimal, dan 64 adalah jumlah bit yang dipakai setiap nilainya. Go punya tipe angka lain, tapi untuk sekarang buku ini hanya butuh int dan float64.

Nilai nol

Kamu bisa mendeklarasikan variabel dengan var tanpa memberinya nilai. Go lalu mengisinya dengan nilai nol (zero value) dari tipenya:

Tipe Nilai nol
int 0
float64 0
bool false
string "" (string kosong)
var score int
var price float64
var alive bool
var name string

fmt.Println(score)
fmt.Println(price)
fmt.Println(alive)
fmt.Println("[" + name + "]") // kurung siku memperlihatkan string kosong

Output:

0
0
false
[]

Ini ada di exercises/11/04-zero-values.go. Jadi variabel Go selalu menyimpan nilai sungguhan dari tipenya, sejak saat dideklarasikan.

Variabel tetap pada tipenya

Nilai variabel bisa berubah, tapi tipenya tidak. Begitu score menjadi int, variabel itu hanya bisa menyimpan int. Compiler memeriksa hal ini sebelum apa pun dijalankan, dan pemeriksaan inilah yang membuat Go disebut bertipe statis (statically typed).

Buka exercises/11/05-wrong-type.go. File ini tidak bisa dikompilasi. Saat pertama dijalankan, hasilnya:

# command-line-arguments
exercises\11\05-wrong-type.go:11:10: cannot use "fifty" (untyped string constant) as int value in assignment

Baca dengan urutan biasa: baris 11, kolom 10. score adalah int, dan "fifty" adalah string. Untyped string constant adalah sebutan Go untuk string yang ditulis langsung di dalam kode. Perbaiki file dengan memberikan angka.

Variabel harus dipakai

Bab 10 sudah menampilkan error ini. Kalau kamu mendeklarasikan variabel dan tidak pernah membacanya, program tidak bisa dikompilasi:

name := "Keiko"
fmt.Println("hi")
name declared and not used

Memberi nilai ke variabel tidak dihitung sebagai memakainya. Hanya membaca nilainya yang dihitung, misalnya dengan mencetaknya. Kalau kamu melihat error ini, pakai variabelnya atau hapus barisnya.

Konstanta

Nilai yang tidak boleh berubah bisa dijadikan konstanta. Tulis const, bukan :=:

const maxLevel = 99
fmt.Println(maxLevel) // 99

Memberi nilai baru sesudahnya adalah error:

const maxLevel = 99
maxLevel = 100
cannot assign to maxLevel (neither addressable nor a map index expression)

Kata-katanya tidak biasa, tapi baris yang disebut adalah baris yang mencoba mengubah konstanta. Gunakan konstanta untuk aturan tetap dalam programmu, seperti level tertinggi, supaya namanya menjelaskan angkanya.

Nama variabel

Kamu yang memilih nama variabel, tapi Go punya aturan tentang nama yang boleh dipakai:

  • Nama boleh berisi huruf, angka, dan garis bawah _.
  • Nama tidak boleh diawali angka. level1 boleh; 1level tidak.
  • Nama membedakan huruf besar dan kecil. Score, score, dan SCORE adalah tiga nama yang berbeda.
  • Nama tidak boleh berupa kata kunci Go: break, case, chan, const, continue, default, defer, else, fallthrough, for, func, go, goto, if, import, interface, map, package, range, return, select, struct, switch, type, var. Kamu akan bertemu sebagian besar kata ini nanti.

Di luar aturan itu, ikuti kebiasaan dari Bab 05:

  • Pilih nama yang bermakna. playerName lebih baik daripada n. hitPoints lebih baik daripada hp kalau kodenya sudah panjang, meskipun hp boleh saja untuk program pendek.
  • camelCase adalah gaya standar Go: maxScore, enemyCount. Awali dengan huruf kecil, karena huruf kapital di awal punya arti khusus yang dijelaskan di Bab 25.

Mencetak variabel

fmt.Println tidak butuh tanda kutip di sekitar nama variabel. Tanda kutip hanya untuk teks yang kamu ketik langsung. Untuk menggabungkan label dengan variabel, berikan sebagai argument terpisah atau gunakan fmt.Printf dari Bab 09:

level := 7
fmt.Println("Level:", level)     // Level: 7
fmt.Printf("Level: %d\n", level) // Level: 7

%s untuk string dan %d untuk bilangan bulat. Penanda ketiga, %v, mencetak nilai apa pun dalam bentuk biasanya, sehingga praktis untuk bool:

alive := true
fmt.Printf("Alive: %v\n", alive) // Alive: true

fmt.Println("Level:", level) mencetak spasi di antara setiap argument secara otomatis. fmt.Printf mencetak persis apa yang kamu tulis, jadi kamu mengontrol setiap karakter. Keduanya benar; fmt.Printf memberi kontrol lebih. Bab 14 membahas penanda-penanda ini secara lengkap.

Assignment ganda

Go membolehkan kamu mendeklarasikan beberapa variabel dan memberi beberapa nilai dalam satu baris. Nama di kiri berpasangan dengan nilai di kanan sesuai posisinya:

name, level := "Keiko", 7
fmt.Println(name, level) // Keiko 7

Cara ini mengelompokkan deklarasi yang berkaitan dengan rapi. Nilainya boleh berbeda tipe, seperti di sini. Cara ini juga memungkinkan trik yang berguna — menukar dua variabel dalam satu langkah:

a, b := 1, 2
a, b = b, a
fmt.Println(a, b) // 2 1

Go membaca seluruh sisi kanan dulu, baru memberikan nilainya. Jadi a, b = b, a mengambil b dan a yang sekarang dan menaruhnya di tempat yang berlawanan. Baris kedua memakai =, bukan :=, karena a dan b sudah ada. Contoh-contoh ini ada di exercises/11/03-multi-assignment.go.

PR

Starter PR ada di exercises/11/homework/. Setiap starter bisa langsung dijalankan dan mencetak baris pengganti. Ganti baris itu dengan kodemu sendiri. Kalau starter sudah punya variabel, baris pengganti juga mencetaknya, karena Go tidak mau mengompilasi variabel yang tidak pernah dibaca.

Soal 1 — Data pemain

Buka exercises/11/homework/01-player-vitals.go. Deklarasikan empat variabel bernama name, level, hitPoints, dan alive, dengan nilai pilihanmu. Yang pertama harus string, dua berikutnya bilangan bulat, dan yang keempat bool. Cetak masing-masing di barisnya sendiri dengan label, seperti Name: Keiko.

Soal 2 — Pemeriksa tipe

Buka exercises/11/homework/02-type-checker.go. Gunakan fmt.Printf dengan %T untuk mencetak tipe dari kelima nilai ini, satu per baris:

  • string "world",
  • bilangan bulat 42,
  • bilangan desimal 3.14,
  • bool false,
  • angka 7.0.

Sebelum menjalankannya, tebak jawaban untuk nilai terakhir.

Soal 3 — Ganti nama dan ubah nilai

Buka exercises/11/homework/03-rename-and-reassign.go. File starter punya tiga variabel a, b, dan c dengan nilai yang tampak acak. Ganti namanya menjadi sesuatu yang bermakna sesuai nilainya, cetak dengan label, ubah ketiganya ke nilai baru dengan tipe yang sama, lalu cetak lagi.

Tantangan — Misteri nilai nol

Buka exercises/11/homework/04-zero-value-mystery.go. Deklarasikan variabel string dengan var tanpa memberinya nilai. Cetak nilainya di antara kurung siku dan tipenya dengan %T. Lalu beri nilai string dan cetak keduanya lagi. Tambahkan blok komentar pendek (beberapa baris yang diawali //) yang menjelaskan, dengan kata-katamu sendiri, apa itu nilai nol.

Stuck atau sudah selesai? Buka halaman solusi PR.