Topik ini memperkenalkan tipe data dasar Go, yaitu tipe bilangan bulat, tipe bilangan pecahan, string, dan bool, lalu membahas aturan konversi tipe yang hanya dapat dilakukan secara eksplisit. Pemahaman tipe dasar menentukan kebenaran operasi aritmetika dan perbandingan pada hampir semua program. Setelah membaca topik ini, setiap tipe dasar dapat dipilih sesuai kebutuhan, dan alasan kompilator menolak pencampuran tipe dapat dijelaskan.
Tipe bilangan bulat#
Tipe bilangan bulat yang paling sering dipakai adalah int, yaitu bilangan bulat bertanda yang ukurannya mengikuti platform. Pada komputer 64-bit, int berukuran 64 bit, sedangkan pada perangkat 32-bit ukurannya 32 bit. Go juga menyediakan ukuran tetap seperti int8, int16, int32, dan int64, beserta versi tak bertandanya yaitu uint dan uint8 hingga uint64, yang berguna ketika rentang nilai dan ukuran memori harus dikontrol ketat. Program berikut menampilkan ukuran int beserta batas nilainya pada lingkungan tempat program dijalankan:
package main
import (
"fmt"
"math"
"strconv"
)
func main() {
fmt.Println("Ukuran tipe int di lingkungan ini :", strconv.IntSize, "bit")
fmt.Println("Nilai minimum int di lingkungan ini:", math.MinInt)
fmt.Println("Nilai maksimum int di lingkungan ini:", math.MaxInt)
}Ukuran tipe int di lingkungan ini : 64 bit
Nilai minimum int di lingkungan ini: -9223372036854775808
Nilai maksimum int di lingkungan ini: 9223372036854775807Keluaran di atas berlaku untuk lingkungan 64-bit tempat program ini dijalankan. Konstanta strconv.IntSize, math.MinInt, dan math.MaxInt dibaca saat kompilasi, sehingga program yang sama di mesin 32-bit akan melaporkan ukuran 32 bit dan batas yang berbeda. Karena itulah kode portabel sebaiknya tidak mengasumsikan ukuran int, melainkan membiarkan konstanta tersebut menyatakan batasnya.
Tipe bilangan pecahan#
Tipe pecahan bawaan untuk deklarasi dan inferensi adalah float64, yaitu bilangan titik apung berpresisi ganda sesuai standar IEEE 754. Menulis 36.5 tanpa tipe menghasilkan float64, sedangkan float32 dipakai secara eksplisit ketika hemat memori lebih penting daripada presisi, misalnya pada larik nilai sensor berukuran besar. Operasi pecahan memiliki satu sifat yang perlu diingat, yaitu hasilnya merupakan pendekatan. Perbandingan kesamaan dua hasil hitung pecahan harus dilakukan terhadap batas toleransi, bukan dengan == langsung.
Pembagian bilangan bulat juga memiliki jebakan yang sering ditemui. Ekspresi 135 / 60 dengan kedua operan bertipe int menghasilkan 2, bukan 2.25, karena pembagiannya adalah pembagian bulat yang membuang sisa. Sisa pembagiannya diperoleh lewat operator %. Program pada bagian konversi di bawah memperlihatkan pola ini secara utuh.
Tipe string dan bool#
Tipe string menyimpan deretan byte yang tidak dapat diubah (immutable), dan zero value-nya adalah string kosong "". Tipe bool hanya memiliki dua nilai, yaitu true dan false, dan menjadi tipe kembalian seluruh operator perbandingan serta syarat pada if. Tidak ada konversi otomatis dari bool ke bilangan maupun sebaliknya, sehingga idiom Go menolak pola if flag == true karena redundan. Bentuk if flag saja sudah mencukupi.
Batasannya tidak berhenti di situ. Angka yang tersimpan sebagai string, misalnya hasil masukan pengguna, tidak dapat langsung dihitung. Konversi antara string dan bilangan dilakukan lewat package strconv dengan fungsi seperti strconv.Atoi, yang dibahas pada modul pustaka standar. Pemisahan peran ini memastikan kegagalan penguraian teks muncul sebagai nilai kembalian yang dapat diperiksa, bukan sebagai perilaku tersembunyi.
Konversi tipe hanya eksplisit#
Go tidak melakukan konversi aritmetika secara otomatis. Menjumlahkan int dengan float64 adalah error kompilasi, bukan operasi yang diam-diam menaikkan tipenya. Aturan ini memang terasa kaku dibanding bahasa yang memakai konversi otomatis, tetapi ia menghilangkan seluruh kelas kejutan presisi dan menambah kejelasan. Konversi dilakukan dengan bentuk T(nilai), seperti pada program berikut:
package main
import "fmt"
func main() {
totalMenit := 135
jam := totalMenit / 60
sisaMenit := totalMenit % 60
fmt.Println(totalMenit, "menit sama dengan", jam, "jam", sisaMenit, "menit")
meter := 3200
kilometer := float64(meter) / 1000.0
fmt.Println(meter, "meter sama dengan", kilometer, "kilometer")
}135 menit sama dengan 2 jam 15 menit
3200 meter sama dengan 3.2 kilometerBaris pertama memperlihatkan pembagian bulat yang sengaja dipakai, yaitu 135 / 60 menghasilkan 2 dan 135 % 60 menghasilkan 15. Baris konversi memperlihatkan pola yang wajib dihafal, yaitu kedua operan dikonversi ke tipe yang sama sebelum dibagi, sehingga float64(meter) / 1000.0 menghasilkan 3.2 dan bukan 3. Apabila konversi dilewatkan, kompilator menolaknya dengan pesan yang eksplisit.
// tidak-dijalankan
var meter int = 3200
var kaki float64 = 10.5
var total float64 = meter + kaki // error kompilasi: mismatched types int and float64Perbaikannya adalah mengonversi salah satu operan, misalnya float64(meter) + kaki. Konversi nilai pecahan ke bilangan bulat memotong bagian di belakang titik menuju nol, sehingga nilai 3.99 menghasilkan 3, dan pemangkasan itu berlaku tanpa pembulatan.
Kesalahan umum#
Kesalahan pertama adalah mengandalkan pembagian bulat padahal hasil pecahan diharapkan. Gejala yang tampak adalah keluaran 3 padahal perhitungan tangan menyebut 3.2. Perbaikannya adalah mengonversi minimal satu operan ke float64 sebelum pembagian, sebagaimana pada contoh konversi jarak di atas.
Kesalahan kedua adalah membandingkan hasil dua perhitungan pecahan dengan ==. Dua variabel float64 berisi 0.1 dan 0.2 menghasilkan penjumlahan yang sedikit meleset dari 0.3 karena representasi biner titik apung, sehingga perbandingan kesamaannya bernilai false. Bandingkan selisihnya terhadap toleransi kecil, atau simpan nilai yang butuh presisi desimal persis dalam bentuk lain, misalnya jumlah sen dalam bilangan bulat.
Ringkasan#
intberukuran mengikuti platform, sedangkanint8hinggaint64danuintberukuran tetap dan eksplisit.- Inferensi bilangan dengan titik desimal menghasilkan
float64, dan pembagian dua bilangan bulat membuang sisa hasilnya. - Konversi tipe di Go hanya eksplisit dengan bentuk
T(nilai), dan pencampuranintdenganfloat64ditolak saat kompilasi. - Konversi pecahan ke bilangan bulat memotong menuju nol, sedangkan konversi antar tipe bilangan tidak memeriksa kelebihan rentang.
Referensi#
- A Tour of Go: Basic types — Go Documentation — Daftar tipe dasar resmi beserta latihan pengetikan dan konversinya.
- The Go Blog: Constants — The Go Blog — Latar aturan numerik Go, termasuk alasan konversi antar tipe dibuat eksplisit.
- The Go Programming Language Specification — The Go Project — Spesifikasi resmi tipe numerik, konversi, dan presisi titik apung.