Interface
Mendefinisikan kontrak perilaku dan polimorfisme ala Go.
Interface = daftar kemampuan
Interface mendefinisikan method apa saja yang harus dimiliki sebuah tipe, tanpa peduli bagaimana tipe itu menyimpan datanya.
type Bentuk interface {
Luas() float64
}
Implementasi implisit
Di Go tidak ada kata implements. Sebuah tipe otomatis memenuhi interface jika memiliki semua method-nya.
type Persegi struct{ Sisi float64 }
func (p Persegi) Luas() float64 { return p.Sisi * p.Sisi }
type Lingkaran struct{ R float64 }
func (l Lingkaran) Luas() float64 { return math.Pi * l.R * l.R }
Keduanya otomatis menjadi Bentuk tanpa deklarasi tambahan. Ini membuat kode longgar-terikat (loosely coupled).
Polimorfisme
func cetakLuas(b Bentuk) {
fmt.Printf("%.2f\n", b.Luas())
}
cetakLuas(Persegi{4}) // 16.00
cetakLuas(Lingkaran{3}) // 28.27
semua := []Bentuk{Persegi{4}, Lingkaran{3}}
for _, b := range semua {
fmt.Println(b.Luas())
}
Satu pemanggilan b.Luas(), perilakunya mengikuti tipe aslinya.
Interface kosong dan any
interface{} (atau alias any) dipenuhi oleh semua tipe. Berguna untuk data yang tipenya bebas, tetapi kamu kehilangan keamanan tipe.
Type assertion & type switch
Mengambil kembali tipe asli dari interface:
var x any = "halo"
s, ok := x.(string) // s = "halo", ok = true
switch v := x.(type) {
case int: fmt.Println("int", v)
case string: fmt.Println("string", v)
}
Interface kecil itu bagus
Interface terbaik di Go itu kecil (1-2 method). Contoh dari standard library: io.Reader (Read), io.Writer (Write), fmt.Stringer (String), error (Error).
Nilai nil di interface
Interface berisi pasangan (tipe, nilai). Interface baru benar-benar nil jika keduanya kosong — jebakan klasik saat mengembalikan pointer nil sebagai error.