Chapter Inferensi Tipe
diakhiri dengan pertanyaan: mengapa Go menolak umur = 36.6 alih-alih mengonversi angkanya otomatis? Jawabannya keputusan desain yang sengaja — semua konversi tipe harus dituliskan eksplisit oleh programmer, sehingga setiap perubahan representasi data terlihat jelas dan tidak pernah terjadi diam-diam. Pada chapter ini kita mempelajari bentuk konversi T(x), perilakunya pada bilangan, jebakan konversi ke string, serta konsekuensi konversi yang menyempit.
Konversi Selalu Ditulis Eksplisit #
Sintaks konversi Go adalah T(x): nama tipe tujuan diikuti nilai dalam tanda kurung. Compiler tidak pernah menyisipkan konversi otomatis, bahkan untuk pasangan tipe yang “hampir sama” seperti int dan float64:
jumlah := 3
harga := 15000.0
total := jumlah * harga // galat kompilasiKompilasi potongan di atas gagal dengan pesan invalid operation: jumlah * harga (mismatched types int and float64). Agar perkalian sah, salah satu operan harus dikonversi eksplisit: float64(jumlah) * harga atau jumlah * int(harga) — pilihan yang mana pun kini menjadi tanggung jawab kita, bukan kebiasaan compiler.
Konversi Numerik: Perluasan dan Pemangkasan #
Konversi dari tipe sempit ke tipe lebar (int8 ke int64, int ke float64) hampir selalu aman. Arah sebaliknya perlu ketelitian karena dua hal berbeda terjadi: desimal ke bulat membuang pecahan, dan bulat ke tipe sempit membuang bit tinggi yang tidak muat.
Konversi int(berat) pada nilai 72.9 menghasilkan 72 — pecahan dipangkas menuju nol, bukan dibulatkan; pembulatan sejati membutuhkan math.Round lebih dulu. Untuk lebar tipe, int8(besar) pada variabel besar := 300 menghasilkan 44 karena hanya 8 bit terakhir yang tersisa. Konstanta murni diperiksa saat kompilasi: int8(300) langsung ditolak dengan pesan constant 300 overflows int8.
Rune ke String dan Jebakan string(65) #
Konversi string(huruf) dari sebuah rune menghasilkan string satu karakter yang diwakili rune tersebut. Masalahnya, tipe rune adalah int32 — sehingga string(65) pun sah secara sintaks, dan hasilnya adalah "A" (rune 65), bukan "65" (teks angka):
huruf := 'A'
fmt.Println(string(huruf)) // A
fmt.Println(string(65)) // A, bukan "65"!Konversi String dan []byte #
Konversi antara string dan []byte sudah dipraktikkan pada chapter Byte dan Encoding
: []byte(nama) menyalin isi string ke deret byte yang bisa diubah, dan string(data) menyalin kembali menjadi string. Keduanya menyalin data, sehingga perubahan di satu sisi tidak memengaruhi sisi lainnya.
Overflow pada Konversi Bilangan Bulat #
Aritmetika pada tipe sempit bekerja modulo rentangnya: int8 di batas atas 127 membungkus ke −128 ketika ditambah satu — tanpa galat runtime, tanpa peringatan. Program utuh di bawah membuktikan perilaku ini secara nyata.
Program Utuh #
Berkas konversi-demo.go merangkai kelima keluarga konversi di atas. Jalankan berkas tersebut dari direktori chapter:
go run konversi-demo.gopackage main
import (
"fmt"
"strconv"
)
func main() {
harga := 150000
rataTiga := float64(harga) / 3
fmt.Println("Rata-rata:", rataTiga)
berat := 72.9
fmt.Println("Berat dibulatkan ke bawah:", int(berat))
huruf := 'A'
fmt.Println("Rune jadi string:", string(huruf))
fmt.Println("string(65) :", string(65))
fmt.Println("strconv.Itoa(65):", strconv.Itoa(65))
nama := "Siti"
data := []byte(nama)
fmt.Println("[]byte:", data, "kembali:", string(data))
nilai := int8(127)
nilai++
fmt.Println("127 + 1 =", nilai)
}Output yang Dihasilkan:
Rata-rata: 50000
Berat dibulatkan ke bawah: 72
Rune jadi string: A
string(65) : A
strconv.Itoa(65): 65
[]byte: [83 105 116 105] kembali: Siti
127 + 1 = -128Mari kita telaah baris demi baris program di atas:
- Baris 11 (
rataTiga := float64(harga) / 3): mengonversihargabertipeintmenjadifloat64sebelum dibagi tiga, sehingga hasilnya tetap presisi desimal — di sini tepat50000. - Baris 15 (
int(berat)): memangkas72.9menjadi72karena konversi desimal ke bulat membuang pecahan, bukan membulatkan. - Baris 18 (
string(huruf)): mengonversi rune'A'menjadi string"A"— konversi rune ke string memang tampil sebagai karakter. - Baris 20–21: membandingkan dua fungsi berbeda hasil —
string(65)menghasilkan"A"karena 65 dibaca sebagai rune, sedangkanstrconv.Itoa(65)menghasilkan teks"65". - Baris 24–25 (
[]byte(nama)danstring(data)): berpindah dari string ke deret byte dan kembali; angka[83 105 116 105]adalah kode byteS,i,t,i. - Baris 27–29 (
nilai++): menambahint8bernilai 127 dengan satu; hasil cetaknya −128, bukti pembungkusan melewati batas atas tipe.
Angka dan Teks dengan strconv #
Package strconv adalah pusat konversi teks dan angka: strconv.Itoa dari bilangan bulat ke teks, strconv.Atoi untuk arah sebaliknya, plus varian ParseFloat. Pembahasan lengkapnya menunggu chapter Package strconv
.
Konversi eksplisit tampak cerewet di awal, tetapi setiap float64(...) adalah pernyataan sadar bahwa representasi data berubah di titik tersebut. Galat yang umum di bahasa lain — desimal diam-diam menjadi bulat, angka diam-diam menjadi karakter — tidak akan lolos tanpa kita tulis sendiri. Selanjutnya: teknik deklarasi banyak variabel sekaligus dalam satu baris.
Referensi #
- Spesifikasi Go: Conversions — aturan resmi seluruh bentuk konversi tipe.
- Dokumentasi package strconv — konversi string dan angka secara resmi.
- Spesifikasi Go: Numeric types — rentang tipe yang menentukan perilaku overflow.
Berkas Sumber
Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.
konversi-demo.go
Unduh berkaspackage main
import (
"fmt"
"strconv"
)
func main() {
harga := 150000
rataTiga := float64(harga) / 3
fmt.Println("Rata-rata:", rataTiga)
berat := 72.9
fmt.Println("Berat dibulatkan ke bawah:", int(berat))
huruf := 'A'
fmt.Println("Rune jadi string:", string(huruf))
fmt.Println("string(65) :", string(65))
fmt.Println("strconv.Itoa(65):", strconv.Itoa(65))
nama := "Siti"
data := []byte(nama)
fmt.Println("[]byte:", data, "kembali:", string(data))
nilai := int8(127)
nilai++
fmt.Println("127 + 1 =", nilai)
}