Rumah > pembangunan bahagian belakang > Golang > Mengapakah panggilan antara muka dalam program Go saya gagal?

Mengapakah panggilan antara muka dalam program Go saya gagal?

WBOY
Lepaskan: 2023-06-10 09:18:06
asal
923 orang telah melayarinya

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.

  1. Antara muka bukan penuding

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.

  1. Ketidakpadanan jenis antara muka

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)
}
Salin selepas log masuk

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)
Salin selepas log masuk

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.

  1. Pelaksanaan antara muka yang tidak lengkap

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)
}
Salin selepas log masuk

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)
Salin selepas log masuk

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.

  1. Antara muka ditindih dengan nilai sifar

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))
}
Salin selepas log masuk

Kod di atas akan menghasilkan ralat berikut:

panic: runtime error: invalid memory address or nil pointer dereference
Salin selepas log masuk

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))
    }
}
Salin selepas log masuk
  1. Jujukan panggilan antara muka

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()
}
Salin selepas log masuk

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:

  • Pastikan anda menetapkan nilai jenis penunjuk pada antara muka.
  • Memastikan semua kaedah antara muka dilaksanakan pada jenis yang ditentukan.
  • Pastikan nilai sebelum memanggil antara muka tidak sifar, atau gunakan penegasan jenis untuk menentukan bahawa antara muka itu bukan nilai sifar.
  • Jika kami menggunakan nilai jenis bukan penunjuk untuk panggilan kaedah dalam antara muka, pastikan anda menggunakan jenis yang betul.

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!

Label berkaitan:
sumber:php.cn
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan