← Kembali ke kursus
Pelajaran kursus · Go
Pelajaran 24

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`.