Menu

Const di Golang: Konstanta Bertipe dan Tanpa Tipe

Cara kerja const di Go: mendeklarasikan konstanta, perbedaan konstanta bertipe dan tanpa tipe, ekspresi konstanta dengan presisi tak terbatas, dan kenapa Go tidak punya konstanta berupa slice, map, atau struct.

Halaman ini dilengkapi editor yang bisa dijalankan. Edit, jalankan, dan lihat output-nya seketika.

Konstanta adalah nilai yang sudah tetap saat kompilasi. Deklarasikan dengan const, dan Go akan menolak setiap upaya untuk mengubahnya.

Konstanta bisa dideklarasikan di level package atau di dalam fungsi, satu per baris atau dikelompokkan dalam blok const ( ... ). MB dan GB dihitung dari konstanta lain, dan compiler melakukan aritmetika itu sekali saja, saat build.

Meng-assign nilai ke konstanta, seperti MaxRetries = 5, adalah error kompilasi:

./main.go:8:2: cannot assign to MaxRetries (neither addressable nor a map index expression)

Apa yang Bisa Menjadi Konstanta

Hanya tiga jenis nilai: boolean, angka (integer, float, bilangan kompleks, dan rune) dan string. Nilainya harus bisa dihitung oleh compiler, artinya literal, konstanta lain, aritmetika atas keduanya, dan beberapa fungsi bawaan seperti len dari string konstanta.

Apa pun yang perlu menjalankan kode atau mengalokasikan memori tidak bisa:

const Colors = []string{"red", "green"} // slice
const Started = time.Now()              // function call
./main.go:9:16: []string{…} (value of type []string) is not constant
./main.go:10:13: time.Now() (value of struct type time.Time) is not constant

Kenapa Go Tidak Punya Konstanta Slice atau Map

Slice, map, dan struct yang berisi keduanya adalah referensi ke memori yang ada saat program berjalan, jadi compiler tidak bisa menanamkannya ke dalam program sebagai nilai tetap, dan Go tidak punya modifier readonly atau final untuk variabel. Cara mengakalinya yang umum:

Salinan itu butuh satu alokasi per pemanggilan, dan itu tidak masalah untuk data seukuran konfigurasi. Untuk pencarian berdasarkan key, switch di dalam fungsi adalah pilihan lain yang mirip konstanta: func statusText(code int) string { switch code { ... } }.

Konstanta Tanpa Tipe

Konstanta yang dideklarasikan tanpa tipe disebut untyped (tanpa tipe). Konstanta ini punya jenis (integer, float, rune, string, bool) tetapi belum punya tipe Go tertentu sampai dipakai, dan ia menyesuaikan diri dengan konteksnya:

Ratio bisa dipakai sebagai int, float64, uint8, dan float32 tanpa konversi. Karena itulah time.Sleep(2 * time.Second) bisa dikompilasi: 2 tidak bertipe dan menjadi time.Duration.

Kalau konteksnya tidak menuntut tipe tertentu, seperti pada x := Ratio, konstanta itu mendapat tipe default:

Jenis konstanta tanpa tipeTipe default
integer (42)int
floating-point (4.2)float64
rune ('a')rune (int32)
kompleks (2i)complex128
stringstring
booleanbool

Aritmetika eksak

Konstanta numerik tanpa tipe bersifat eksak. Compiler merepresentasikan integer dengan minimal 256 bit, jadi nilai di tengah perhitungan bisa jauh lebih besar dari tipe Go mana pun:

Huge sendiri tidak bisa dicetak sebagai integer, karena mengirimnya ke fmt.Println mengonversinya ke int, dan compiler menangkap hal itu (float64(Huge) bisa, karena float sanggup menampung besarnya):

cannot use Huge (untyped int constant 1267650600228229401496703205376) as int value in argument to fmt.Println (overflows)

Pemeriksaan yang sama menghentikan kesalahan yang lebih kecil saat kompilasi, seperti var b byte = 300:

cannot use 300 (untyped int constant) as byte value in variable declaration (overflows)

Konstanta Bertipe

Beri konstanta sebuah tipe dan ia akan berperilaku seperti nilai bertipe itu di mana pun, termasuk penolakan Go untuk mencampur tipe:

const Limit int = 10

var f float64 = 2
fmt.Println(Limit * f)
invalid operation: Limit * f (mismatched types int and float64)

Dengan const Limit = 10 (tanpa tipe), Limit * f bisa dikompilasi dan menghasilkan 20. Jadi biarkan konstanta tanpa tipe kecuali tipenya punya makna. Tipe punya makna saat kamu mendeklarasikan konstanta dengan tipe bernama milikmu sendiri, dan begitulah cara Go membangun enum:

type Weekday int

const (
	Sunday Weekday = iota
	Monday
	Tuesday
)

Di sini tipenya justru intinya: fungsi yang menerima Weekday mendokumentasikan apa yang ia butuhkan. iota dan pola enum yang dibangun di atasnya dibahas di halaman enum dan iota.

const vs var

constvar
Bisa berubahtidakya
Nilainya diketahuisaat kompilasisaat program berjalan
Tipe yang diizinkanbool, numerik, stringapa saja
Memakai memori saat program berjalantidakya
Bisa diambil alamatnya (&x)tidakya
Yang tidak terpakai menjadi errortidakya, untuk variabel lokal

Pakai const untuk apa pun yang benar-benar tetap: batas, ukuran, nama, kode protokol, string format. Kamu mendapat pemeriksaan overflow saat kompilasi dan aritmetika eksak secara gratis.

Hal yang Sering Menjebak

Konstanta bertipe tidak menyesuaikan diri. const Timeout int = 5 tidak bisa dikirim ke tempat yang mengharapkan time.Duration tanpa konversi; const Timeout = 5 yang tanpa tipe bisa dikalikan: Timeout * time.Second.

Pembagian integer terjadi pada konstanta integer. const Half = 1 / 2 bernilai 0, karena kedua operand adalah integer tanpa tipe. Tulis 1.0 / 2 untuk mendapat 0.5.

Tidak punya alamat. &MaxRetries tidak bisa dikompilasi. Kalau sebuah API meminta *int, salin dulu konstantanya ke sebuah variabel.

Pertanyaan yang sering diajukan

Bagaimana cara mendeklarasikan konstanta di Go?

Dengan const: const MaxRetries = 3 atau, dengan tipe eksplisit, const Timeout time.Duration = 5 * time.Second. Kelompokkan beberapa konstanta dalam satu blok: const ( A = 1; B = 2 ). Nilainya harus bisa dihitung saat kompilasi.

Apakah bisa membuat slice, map, atau array const di Go?

Tidak bisa. Konstanta hanya boleh berupa boolean, angka (termasuk rune), dan string. const Colors = []string{"red"} gagal dengan is not constant. Pakai var di level package, dan kalau pemanggil tidak boleh mengubahnya, sediakan fungsi yang mengembalikan salinan baru.

Apa itu konstanta tanpa tipe (untyped constant) di Go?

Konstanta yang dideklarasikan tanpa tipe, seperti const Pi = 3.14159. Konstanta ini belum punya tipe tetap sampai dipakai, jadi konstanta yang sama bisa berfungsi sebagai float32, float64, atau, kalau nilainya memungkinkan, int. Konstanta tanpa tipe juga eksak: compiler menyimpan presisi minimal 256 bit, jadi const Big = 1 << 100 sah selama kamu hanya memakainya di ekspresi yang hasilnya muat.

Apa bedanya const dan var di Go?

const sudah tetap saat kompilasi dan tidak pernah bisa berubah; ia tidak memakai memori saat program berjalan dan hanya bisa berisi bool, angka, atau string. var adalah lokasi memori yang bisa di-assign ulang dan bisa berisi tipe apa pun, termasuk nilai yang dihitung saat program berjalan seperti time.Now().

Ilustrasi bahasa pemrograman di Coddy

Belajar coding dengan Coddy

Mulai