Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Mengapa Perlaksanaan Jenis Konkrit Tidak Memuaskan Kaedah Antara Muka Mengembalikan Antara Muka dalam Go?

Mengapa Perlaksanaan Jenis Konkrit Tidak Memuaskan Kaedah Antara Muka Mengembalikan Antara Muka dalam Go?

DDD
DDDasal
2024-10-26 22:48:03334semak imbas

Why Doesn't a Concrete Type Implementation Satisfy an Interface Method Returning an Interface in Go?

Kaedah Antara Muka Mengembalikan Ketidakpadanan Antara Muka dengan Pelaksanaan Jenis Konkrit

Dalam Go, kaedah antara muka yang mengembalikan antara muka hanya sepadan dengan pelaksanaan yang mengisytiharkan antara muka itu sendiri, bukan konkrit jenis yang melaksanakan antara muka. Pertimbangkan contoh berikut:

<code class="go">package main

import "fmt"

type Foo struct {
    val string
}

func (f *Foo) String() string {
    return f.val
}

type StringerGetter interface {
    GetStringer() fmt.Stringer
}

type Bar struct{}

func (b *Bar) GetStringer() *Foo {
    return &Foo{"foo"}
}

func Printer(s StringerGetter) {
    fmt.Println(s.GetStringer())
}

func main() {
    f := Bar{}
    Printer(&f) // compile-time error
}</code>

Kod ini memberikan ralat masa kompilasi berikut:

cannot use &f (type *Bar) as type StringerGetter in argument to Printer:  *Bar does not implement StringerGetter (wrong type for GetStringer method)

Untuk menyelesaikan isu ini, sama ada kaedah GetStringer dalam jenis Bar harus mengembalikan fmt .Antara muka Stringer bukannya konkrit *Jenis Foo, atau antara muka StringerGetter harus diubah suai untuk menerima jenis konkrit dan bukannya antara muka.

Penyelesaian Alternatif

Dalam kes di mana mengubah suai jenis konkrit luaran atau antara muka yang dikongsi tidak diingini, terdapat dua penyelesaian alternatif:

  1. Mencipta Jenis Pembungkus: Anda boleh mencipta jenis baharu yang membalut jenis konkrit luaran dan melaksanakan yang dikehendaki antara muka. Contohnya:
<code class="go">type MyBar struct {
    Bar
}

func (b *MyBar) GetStringer() fmt.Stringer {
    return b.Bar.GetStringer()
}</code>
  1. Membenamkan Jenis Konkrit: Sebagai alternatif, anda boleh membenamkan jenis konkrit luaran dalam jenis anda sendiri dan melaksanakan antara muka menggunakan jenis terbenam kaedah. Contohnya:
<code class="go">type MyBar struct {
    embed Bar
}

func (b *MyBar) GetStringer() fmt.Stringer {
    return b.GetStringer()
}</code>

Kedua-dua pendekatan membolehkan anda bekerja dengan jenis konkrit luaran sambil menyediakan pelaksanaan antara muka yang diingini tanpa mengubah suai jenis asal atau antara muka yang dikongsi.

Atas ialah kandungan terperinci Mengapa Perlaksanaan Jenis Konkrit Tidak Memuaskan Kaedah Antara Muka Mengembalikan Antara Muka dalam Go?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
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