Pelajaran modul (2/5)
Ketik pernyataan
Pernyataan tipe mengekstrak tipe konkret dari nilai antarmuka.
Anda memerlukannya ketika Anda memiliki interface{} (atau antarmuka "tinggi") di
tangan dan perlu memperlakukannya sebagai tipe spesifiknya untuk mengakses bidang atau
metode tidak ada di antarmuka.
Sintaksis
var i interface{} = "ciao"
s := i.(string) // "panic" form: panics if it's not a string
s, ok := i.(string) // "comma ok" form: ok = false if it's not a stringDua bentuk, dua semantik:
| Formulir | Sukses | Kegagalan |
|---|---|---|
v := i.(T) | v = nilai tipe T | panik saat runtime |
v, ok := i.(T) | v=..., ok=true | v = nilai T nol, ok=false |
Formulir "Koma oke": paling aman
var i interface{} = 42
if s, ok := i.(string); ok {
fmt.Println("è stringa:", s)
} else {
fmt.Println("non è stringa, ignoro")
}ok memungkinkan Anda menangani kasus "tipe yang salah" tanpa panik. Itu adalah
pola idiomatik dalam sebagian besar kasus.
Penegasan ke antarmuka
Penegasan ini tidak hanya berlaku pada tipe konkret, tetapi juga pada tipe lainnya antarmuka:
type Closer interface { Close() error }
func tryClose(x interface{}) {
if c, ok := x.(Closer); ok {
c.Close()
}
}Pola yang sangat umum di perpustakaan standar: "jika masukan saya juga
dan io.Closer, panggil Close di akhir".
Penegasan tentang pointer vs nilai
Pernyataan tersebut harus cocok dengan tipe dinamis PERSIS:
type Cat struct{}
func (c *Cat) Meow() {}
var a interface{} = &Cat{}
c1, ok := a.(*Cat) // ok = true
c2, ok := a.(Cat) // ok = false: it holds *Cat, not Cat*Cat dan Cat adalah tipe berbeda untuk sistem tipe.
Kapan menggunakan pernyataan vs saklar tipe
- Hanya 1 kemungkinan jenis, pemeriksaan "deteksi fitur" (misalnya, dilemparkan ke antarmuka opsional): ketik pernyataan dengan
comma ok. - 2+ kemungkinan jenis, pengiriman ke beberapa cabang: ketik saklar (pelajaran berikutnya).
Cobalah
Gunakan pola koma ok untuk mengekstrak string dari i.
Tunjukkan petunjuk
Sintaks: `v, oke := i.(T)`.
Solusi tersedia setelah 3 upaya
Ketik pernyataan ke int tanpa koma ok (anggap saya mengandung int).
Tunjukkan petunjuk
Tanpa `ok` Anda menganggap tipenya pasti; jika tidak, panik.
Solusi tersedia setelah 3 upaya
Apa yang terjadi dengan `s := i.(string)` jika saya berisi int?
var i interface{} = 42
s := i.(string)Rekap
v := i.(T): panik jika tipe dinamis ≠ T.v, ok := i.(T): pola aman, centangok.- Bekerja juga terhadap antarmuka lain ("fitur terdeteksi").
Tdan*Tadalah tipe pernyataan yang berbeda.- 1 jenis → pernyataan; 2+ tipe → tipe sakelar.