Antara Muka Tiada kepada Penuding Penukaran dalam Go
Dalam Go, jenis antara muka boleh menyimpan nilai jenis konkrit berbeza yang melaksanakannya. Walau bagaimanapun, percubaan untuk menukar antara muka sifar kepada penunjuk jenis tertentu boleh mengakibatkan ralat "penukaran antara muka: antara muka adalah sifar, bukan *
Untuk memahami kelakuan ini, pertimbangkan coretan kod daripada soalan:
type Nexter interface { Next() Nexter } type Node struct { next Nexter } func (n *Node) Next() Nexter {...} func main() { var p Nexter var n *Node fmt.Println(n == nil) // True n = p.(*Node) // Error: interface conversion: interface is nil, not *main.Node }
Masalah timbul apabila cuba memberikan nilai p kepada n menggunakan penegasan jenis p.(*Nod). Penegasan ini gagal kerana pembolehubah p adalah sifar, menunjukkan bahawa ia tidak memegang sebarang nilai konkrit.
Sebagai alternatif, ungkapan berikut:
n = (*Node)(nil)
berjaya kerana ia secara eksplisit menetapkan pembolehubah n kepada penunjuk nol jenis *Nod. Ini mungkin kerana nilai antara muka terdiri daripada sepasang (nilai, jenis dinamik) dan menetapkan nilai antara muka kepada sifar akan menghasilkan sepasang (tiada, tiada).
Untuk mengendalikan nilai antara muka tiada, anda boleh menyemaknya secara eksplisit:
if p != nil { n = p.(*Node) // Only succeeds if `p` holds a value of type `*Node` }
Sebagai alternatif, anda boleh menggunakan bentuk jenis "koma-ok" penegasan:
if n, ok := p.(*Node); ok { fmt.Printf("n=%#v\n", n) // Never fails, assigns zero value to `n` if `p` is nil }
Kesimpulannya, cubaan menukar antara muka nil kepada penunjuk jenis tertentu menggunakan penegasan jenis akan gagal, tetapi secara eksplisit menetapkannya kepada nil akan berjaya. Untuk mengendalikan nilai antara muka tiada, semakan eksplisit atau bentuk penegasan jenis "koma-ok" boleh digunakan.
Atas ialah kandungan terperinci Mengapa Antara Muka Nihil kepada Penuding Gagal dalam Go?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!