Rumah > Artikel > pembangunan bahagian belakang > Mengapakah panggilan antara muka dalam program Go saya gagal?
Bahasa Go telah menjadi salah satu bahasa pengaturcaraan paling popular di dunia kerana ciri-cirinya yang pantas dan cekap. Antara muka ialah ciri yang berkuasa dalam bahasa Go, yang menyediakan pengaturcara cara yang sangat elegan untuk berinteraksi dan berkomunikasi antara struktur yang berbeza. Walau bagaimanapun, apabila panggilan antara muka gagal, ini adalah masalah biasa bagi sesetengah pengaturcara baru. Artikel ini akan meneroka sebab mengapa panggilan antara muka gagal dan menyediakan beberapa penyelesaian.
Dalam bahasa Go, apabila data biasanya dihantar ke fungsi, data akan disalin ke parameter fungsi. Dan apabila kita lulus antara muka sebagai parameter kepada fungsi, jika nilai jenis antara muka bukan jenis penunjuk, ia akan disalin sebagai jenis nilai. Ini boleh menyebabkan panggilan antara muka gagal dalam beberapa kes.
Panggilan antara muka dicapai dengan memanggil kaedah nilai antara muka, dan ini memerlukan jenis nilai antara muka untuk menjadi jenis penunjuk, kerana kaedah itu perlu beroperasi pada penunjuk. Jika kami menetapkan nilai jenis bukan penuding kepada antara muka, bahasa Go akan menyalin data dalaman dan mencipta nilai antara muka baharu. Tetapi nilai antara muka baharu ini tidak lagi menjadi jenis penunjuk, jadi kami tidak boleh memanggil kaedah secara langsung pada nilai antara muka baharu ini. Inilah sebabnya mengapa panggilan antara muka gagal.
Jadi, jika kita ingin membuat panggilan ke antara muka dan memastikan ia berfungsi dengan baik, kita perlu memastikan bahawa nilai jenis antara muka ialah jenis penunjuk.
Dalam bahasa Go, jika pembolehubah bukan jenis antara muka, maka ia tidak boleh diberikan kepada jenis antara muka. Ini kerana antara muka adalah jenis dinamik dan ia tidak boleh disemak oleh pengkompil. Jika jenis antara muka tidak sepadan, panggilan antara muka juga akan gagal. Lihat contoh berikut:
type Employee struct { Name string Age int } func (e Employee) ShowName() { fmt.Printf("Name is %s ", e.Name) } func showName(s interface{}) { s.ShowName() } func main() { emp := Employee{Name: "John", Age: 25} showName(emp) }
Kod di atas akan menghasilkan ralat berikut:
cannot use emp (type Employee) as type interface {} in argument to showName: Employee does not implement interface {} (missing ShowName method)
Pengkompil Go akan menganggap bahawa jenis Pekerja ini adalah jenis yang berbeza, jadi ia tidak boleh ditugaskan secara langsung kepada pembolehubah jenis{} antara muka. Untuk menyelesaikan masalah ini, kami boleh mengubah suai jenis Pekerja untuk melaksanakan antara muka yang diperlukan supaya kami boleh menghantarnya sebagai parameter kepada fungsi showName.
Satu lagi kegagalan panggilan antara muka biasa ialah pelaksanaan antara muka yang tidak lengkap. Ringkasnya, ini bermakna kami melaksanakan antara muka pada jenis struct, tetapi tidak melaksanakan semua kaedah antara muka. Ini boleh menyebabkan kegagalan semasa membuat panggilan antara muka. Lihat contoh berikut:
type Square struct { Side int } func (s Square) Area() int { return s.Side * s.Side } type Shape interface { Area() int } func PrintArea(s Shape) { fmt.Println("Area is", s.Area()) } func main() { sq := Square{Side: 5} PrintArea(sq) }
Kod di atas akan menghasilkan ralat berikut:
cannot use sq (type Square) as type Shape in argument to PrintArea: Square does not implement Shape (missing Area method)
Dalam contoh ini, kami telah menentukan jenis Square dan antara muka Bentuk. Kami melaksanakan kaedah Area pada jenis Square. Tetapi kami tidak melaksanakan kaedah lain antara muka Bentuk. Ini menyebabkan panggilan antara muka gagal dalam fungsi PrintArea. Oleh itu, pastikan semua kaedah antara muka dilaksanakan pada jenis yang ditentukan supaya panggilan antara muka boleh berjaya.
Dalam bahasa Go, nilai sifar boleh diberikan kepada antara muka. Ini bermakna bahawa dalam antara muka, kita boleh menghantar nilai sifar sebagai nilai yang sah. Walau bagaimanapun, ini juga boleh menyebabkan panggilan antara muka gagal.
Apabila nilai antara muka adalah sifar, kaedah panggilan padanya akan menyebabkan ralat masa jalan. Lihat contoh berikut:
type Calculator interface { Add(a int, b int) int } func main() { var c Calculator fmt.Println(c.Add(1, 2)) }
Kod di atas akan menghasilkan ralat berikut:
panic: runtime error: invalid memory address or nil pointer dereference
Penyelesaiannya ialah sebelum menggunakan antara muka nilai nil, kita perlu memastikan bahawa jenis antara muka telah dilaksanakan sepenuhnya, atau boleh digunakan Jenis penegasan untuk menentukan sama ada antara muka tidak sifar.
func main() { var c Calculator if c != nil { fmt.Println(c.Add(1, 2)) } }
Dalam bahasa Go, apabila kami menetapkan nilai jenis bukan penuding kepada antara muka, Go akan menyalin data dalaman dan mencipta nilai antara muka baharu. Nilai antara muka baharu ini juga merupakan antara muka yang berbeza dengan nilai yang sama. Oleh itu, apabila kita memanggil kaedah dalam antara muka, kita perlu membuat panggilan kaedah di luar antara muka dengan nilai jenis primitif atau jenis penunjuk kepada nilai primitif.
Lihat contoh berikut:
type Employee struct { Name string Age int } func (e Employee) ShowName() { fmt.Printf("Name is %s ", e.Name) } type NameShower interface { ShowName() } func main() { emp := Employee{Name: "John", Age: 25} var ns NameShower ns = emp ns.ShowName() pemp := &Employee{Name: "Doe", Age: 30} ns = pemp ns.ShowName() }
Dalam kod di atas, kami mentakrifkan jenis Pekerja dan antara muka NameShower. Apabila kita mencipta emp dan menetapkannya kepada ns, panggilan antara muka akan gagal kerana emp bukan jenis penunjuk kepada nilai primitif. Kita perlu menggunakan penunjuk ke emp untuk memanggil kaedah ShowName.
Apabila mencipta pemp dan memberikannya kepada ns, panggilan antara muka akan berjaya kerana pemp ialah jenis penunjuk kepada nilai primitif. Jadi, pastikan kami telah menggunakan jenis yang betul sebelum membuat panggilan antara muka.
Kesimpulan
Melalui artikel ini, kami sudah mengetahui sebab mengapa panggilan antara muka gagal dalam program Go. Seterusnya, mari kita ringkaskan:
Jika anda mengikuti kaedah di atas, panggilan antara muka dalam program Go anda tidak akan gagal.
Atas ialah kandungan terperinci Mengapakah panggilan antara muka dalam program Go saya gagal?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!