Tipe dasar Go adalah angka, boolean, dan string. Setiap variabel punya tepat satu tipe, yang sudah tetap saat kompilasi, dan Go tidak pernah mengonversi antar tipe untukmu. %T mencetak tipe dari nilai apa pun:
Perhatikan bahwa 'G' dicetak sebagai 71 dengan tipe int32: karakter dalam tanda kutip tunggal adalah rune, yaitu sebuah angka (code point Unicode). rune adalah alias untuk int32 (tipe yang sama dengan nama kedua), jadi %T melaporkan int32. Begitu juga byte melaporkan uint8.
Integer
| Tipe | Ukuran | Jangkauan |
|---|---|---|
int8 | 8 bit | -128 sampai 127 |
int16 | 16 bit | -32.768 sampai 32.767 |
int32 | 32 bit | sekitar -2,1 miliar sampai 2,1 miliar |
int64 | 64 bit | sekitar -9,2 kuintiliun sampai 9,2 kuintiliun |
uint8 (byte) | 8 bit | 0 sampai 255 |
uint16 | 16 bit | 0 sampai 65.535 |
uint32 | 32 bit | 0 sampai sekitar 4,3 miliar |
uint64 | 64 bit | 0 sampai sekitar 18,4 kuintiliun |
int, uint | 32 atau 64 bit | ukuran word platform |
uintptr | ukuran platform | menyimpan nilai pointer, untuk kode tingkat rendah |
Pakai int secara default. len() mengembalikan int, indeks slice bertipe int, dan counter loop bertipe int. Di setiap platform 64-bit, int berukuran 64 bit. Pakai tipe berukuran tertentu saat ukurannya menjadi bagian dari kesepakatan: int32 di format file biner, uint8 untuk byte mentah, int64 untuk Unix timestamp dalam nanodetik.
Hindari tipe unsigned untuk besaran yang "tidak mungkin negatif", seperti jumlah. Mengurangi melewati nol akan berputar menjadi angka yang sangat besar, bukan angka negatif yang bisa kamu tangkap.
Batas dan overflow
Package math punya konstanta untuk setiap batas. Saat program berjalan, aritmetika integer yang overflow akan berputar balik diam-diam:
Tidak ada panic, tidak ada error: 127 + 1 menjadi -128. Hanya ekspresi konstanta yang diperiksa saat kompilasi (var b int8 = 128 tidak bisa dikompilasi). Kalau overflow mungkin terjadi pada datamu, periksa sebelum operasinya atau pakai math/big.
Literal integer
million := 1_000_000 // underscores for readability (Go 1.13+)
mask := 0xFF // hexadecimal
perm := 0o755 // octal (also the older form 0755)
flags := 0b1010 // binary
Bilangan Floating-Point
| Tipe | Ukuran | Presisi |
|---|---|---|
float32 | 32 bit | sekitar 6 sampai 9 digit signifikan |
float64 | 64 bit | sekitar 15 sampai 17 digit signifikan |
Literal dengan titik desimal atau eksponen (2.5, 1e6) bertipe float64 secara default, dan package math menerima serta mengembalikan float64. Pakai tipe ini kecuali memori di array besar menjadi masalah.
Float bersifat biner, jadi kebanyakan pecahan desimal hanyalah perkiraan:
Dari sini muncul dua aturan. Jangan pernah membandingkan float dengan == setelah aritmetika. Dan jangan pernah menyimpan uang dalam float: pakai integer berupa jumlah sen, atau library desimal.
Membagi float dengan nol menghasilkan +Inf, -Inf, atau NaN, bukan panic. Membagi integer dengan nol akan panic saat program berjalan (runtime error: integer divide by zero), dan pembagi berupa konstanta nol adalah error kompilasi.
Boolean
bool menyimpan true atau false, dan zero value-nya adalah false. Go tidak memperlakukan angka, string kosong, atau nil sebagai boolean. if count {} adalah error kompilasi; tulis if count > 0 {}. Operatornya adalah &&, ||, dan !, dan && serta || melakukan short-circuit.
String
string adalah urutan byte yang immutable, biasanya berupa teks UTF-8. len(s) menghitung byte, bukan karakter:
é memakai dua byte di UTF-8, jadi len melaporkan 6 untuk lima karakter. String dengan tanda kutip ganda memproses escape seperti \n; raw string dengan backquote tidak, dan bisa terdiri dari beberapa baris. Halaman string membahas package strings, dan halaman rune dan byte membahas UTF-8 secara mendalam.
byte dan rune
| Alias | Sama dengan | Menyimpan |
|---|---|---|
byte | uint8 | satu byte data mentah |
rune | int32 | satu code point Unicode |
Keduanya alias, bukan tipe baru: byte dan uint8 bisa saling dipertukarkan tanpa konversi. Namanya menjelaskan arti angka tersebut.
Bilangan Kompleks
Go punya tipe kompleks bawaan, complex64 dan complex128, dengan real, imag, dan package math/cmplx:
Hanya sedikit program yang membutuhkannya, tetapi pemrosesan sinyal dan sebagian kode numerik memakainya.
Tipe Komposit dan Referensi
Tipe dasar bisa digabungkan menjadi tipe komposit. Masing-masing punya halamannya sendiri:
| Tipe | Contoh | Zero value |
|---|---|---|
| array | [3]int | tiga angka nol |
| slice | []int | nil |
| map | map[string]int | nil |
| struct | struct{ X, Y int } | setiap field bernilai nol |
| pointer | *int | nil |
| fungsi | func(int) int | nil |
| channel | chan int | nil |
| interface | error, any | nil |
any adalah alias untuk interface{} (sejak Go 1.18) dan bisa menyimpan nilai bertipe apa pun.
Tipe Bernama
Kamu bisa mendefinisikan tipe baru dari tipe yang sudah ada. Representasinya sama, tetapi tipenya berbeda, dan tipe itu bisa punya method:
type Celsius float64
type UserID int64
var t Celsius = 21.5
var f float64 = t // compile error: cannot use t (variable of float64 type Celsius) as float64 value in variable declaration
Ketatnya aturan ini justru intinya: UserID tidak bisa tanpa sengaja dikirim ke tempat yang mengharapkan OrderID. Konversi secara eksplisit kalau memang itu maksudmu: float64(t). Lihat konversi tipe untuk aturannya, dan fungsi-fungsi strconv untuk berpindah antara angka dan string.
Zero Value
Setiap tipe punya zero value, yaitu nilai yang disimpan variabel sebelum kamu meng-assign apa pun: 0 untuk angka, false untuk bool, "" untuk string, dan nil untuk pointer, slice, map, channel, fungsi, dan interface. Di Go tidak ada variabel yang belum diinisialisasi.
Pertanyaan yang sering diajukan
Seberapa besar int di Go?
int dan uint berukuran 64 bit di platform 64-bit (amd64, arm64) dan 32 bit di platform 32-bit. Kalau kamu butuh ukuran tetap, untuk format file atau protokol jaringan, pakai int32, int64, uint8, dan seterusnya. Untuk counter, indeks, dan panjang biasa, pakai int.
Bagaimana cara mencetak tipe sebuah variabel di Go?
Pakai verb %T: fmt.Printf("%T\n", x) mencetak int, float64, []string, main.User, dan seterusnya. Di dalam kode, reflect.TypeOf(x) mengembalikan informasi yang sama sebagai nilai yang bisa kamu periksa.
Apa bedanya byte dan rune di Go?
byte adalah alias untuk uint8 dan menyimpan satu byte data mentah. rune adalah alias untuk int32 dan menyimpan satu code point Unicode. String adalah urutan byte; menelusurinya dengan for range akan men-decode-nya menjadi rune.
Sebaiknya pakai float32 atau float64 di Go?
Pakai float64 kecuali ada alasan untuk tidak memakainya. Itulah tipe default dari literal floating-point, tipe yang dipakai package math, dan presisinya sekitar 15 sampai 17 digit desimal signifikan, dibandingkan sekitar 6 sampai 9 untuk float32. Pilih float32 hanya untuk menghemat setengah memori di array besar atau untuk menyesuaikan dengan format eksternal.
Berapa nilai maksimum int di Go?
Pakai konstanta di package math: math.MaxInt (9223372036854775807 di platform 64-bit), math.MinInt, math.MaxInt64, math.MaxUint32, dan seterusnya. Aritmetika yang melewati batas itu akan berputar balik diam-diam saat program berjalan; tidak terjadi panic.