Reflect
Memeriksa tipe dan nilai saat program berjalan.
Pahami konsepnya
Refleksi adalah kemampuan program memeriksa dirinya sendiri: bertanya "ini tipenya apa, berapa field-nya, nilainya berapa" saat berjalan. Go menyediakannya lewat paket reflect, dan kamu sudah merasakan hasilnya tanpa sadar — fmt mencetak struct apa pun, encoding/json mengubah struct menjadi JSON, dan flag membaca nama field: semuanya refleksi di balik layar.
Dua pintu masuk utama: reflect.TypeOf(x) memberi tahu tipe dinamis sebuah nilai, dan reflect.ValueOf(x) membungkus nilainya agar bisa diperiksa — .Kind() melaporkan jenis dasarnya (int, string, struct), .NumField() dan .Field(i) menyusuri field struct, .Interface() mengembalikan nilai aslinya.
Refleksi kuat tapi mahal dan rapuh: melewati pemeriksaan kompilator, lambat dibanding kode biasa, dan error-nya baru muncul saat runtime. Prinsip umum komunitas Go: "refleksi tidak pernah diperlukan, hanya kadang memudahkan" — pakai untuk pustaka serba-guna, hindari di logika aplikasi sehari-hari. Kebutuhan serupa kini sering lebih baik dijawat generics.
Coba contoh kode
package main
import (
"fmt"
"reflect"
)
type Siswa struct {
Nama string
Poin int
}
func main() {
x := 42
fmt.Println(reflect.TypeOf(x).Kind()) // int
s := Siswa{Nama: "Ari", Poin: 10}
t := reflect.TypeOf(s)
for i := 0; i < t.NumField(); i++ {
f := t.Field(i)
fmt.Printf("%s %s\n", f.Name, f.Type)
}
}Kind() melaporkan jenis dasar nilai (int), bukan nama tipe pembuatnya. Untuk struct, TypeOf lalu NumField/Field menyusuri skema fieldnya — nama dan tipenya tercetak tanpa kamu menuliskannya. Inti kerja json.Marshal bekerja persis begini.
Latihan singkat
Uji: cetak nama dan tipe tiap field lewat reflect — harus tiga baris persis: `Nama string`, `Poin int`, `Kelas string`.