editor php Xiaoxin akan membincangkan masalah tentang X gagal melaksanakan Y dalam artikel ini. Dalam masalah ini, kami menggunakan pendekatan penerima penunjuk. Melalui kaedah ini, kita dapat lebih memahami mengapa X tidak dapat mencapai Y dan mencari jalan untuk menyelesaikan masalah ini. Dalam kandungan berikut, kami akan membincangkan masalah ini secara terperinci dan memberikan beberapa penyelesaian.
Sudah ada beberapa Soal Jawab mengenai soalan "X tidak melaksanakan Y (...kaedah mempunyai penerima penunjuk)", tetapi bagi saya mereka seolah-olah bercakap tentang perkara yang berbeza dan tidak terpakai kepada situasi khusus saya.
Jadi daripada membuat soalan itu sangat spesifik, saya akan menjadikannya luas dan abstrak - nampaknya terdapat beberapa situasi berbeza yang boleh menyebabkan ralat ini berlaku, bolehkah seseorang meringkaskannya?
Bagaimana untuk mengelakkan masalah ini dan jika ia berlaku, apakah kemungkinannya? terima kasih.
Ini kesilapan masa kompilasi berlaku apabila anda cuba menetapkan atau lulus (atau membuang) concretetype ke jenis antara muka; .
Ringkasan ringkas: Suatu tugasan kepada pembolehubahJenis antara muka adalah sah jika nilai yang ditetapkan melaksanakan antara muka yang ditetapkan. Jika set kaedah ialah superset antara muka, ia akan melaksanakannya. Set kaedah jenis penunjuk termasuk kaedah dengan penerima penunjuk dan bukan penunjuk. Kaedah yang ditetapkan untuk jenis bukan penunjuk sahaja termasuk kaedah dengan penerima bukan penunjuk.
Mari kita lihat contoh:
type stringer interface { string() string } type mytype struct { value string } func (m *mytype) string() string { return m.value }
stringer
jenis antara muka hanya mempunyai satu kaedah: string()
. Sebarang nilai yang disimpan dalam nilai antara muka stringer
mesti mempunyai kaedah ini. Kami juga mencipta mytype
dan mencipta kaedah mytype.string()
dengan pointerstringer
接口类型只有一个方法:string()
。存储在接口值 stringer
中的任何值都必须具有此方法。我们还创建了一个 mytype
,并创建了一个带有指针接收器的方法 mytype.string()
。这意味着 string()
方法位于 *mytype
类型的 方法集 中,但是不在 mytype
receiver. Ini bermakna kaedah string()
berada dalam
jenis *mytype
, tetapi bukan dalam mytype
. mytype
的值分配给 stringer
kami mendapat ralat berikut: *mytype
类型的值分配给 stringer
m := mytype{value: "something"} var s stringer s = m // cannot use m (type mytype) as type stringer in assignment: // mytype does not implement stringer (string method has pointer receiver)
, semuanya berfungsi dengan baik:
s = &m
fmt.println(s)
):
something
Kemungkinan menyelesaikan masalah:
Struktur dan benam
Apabila menggunakan struct
struct dan embedding
. Seperti contoh ini: mytype2
的方法集不包含内嵌mytype
的string()
方法,只有*mytype2
type mytype2 struct { mytype } m := mytype{value: "something"} m2 := mytype2{mytype: m} var s stringer s = m2 // compile-time error again
): *mytype
并仅使用非指针 mytype2
var s stringer s = &m2
Pergi ke Taman Permainanmytype
或 *mytype
),如果我们使用指针 *mytype2
):
type mytype2 struct {
*mytype
}
m := mytype{value: "something"}
m2 := mytype2{mytype: &m}
var s stringer
s = m2
Pergi ke Taman Permainan):
type mytype2 struct { *mytype } m := mytype{value: "something"} m2 := mytype2{mytype: &m} var s stringer s = &m2
给定一个结构体类型 s
和一个名为 t
的类型,提升的方法包含在该结构体的方法集中,如下所示:
s
包含匿名字段 t
,则 s
和 *s
的方法集均包含接收者为 t
的提升方法。 *s
的方法集还包括接收者 *t
的提升方法。s
包含匿名字段 *t
,则 s
和 *s
的方法集都包含接收者为 t
或 *t
的提升方法。换句话说:如果我们嵌入一个非指针类型,非指针嵌入器的方法集只能获取具有非指针接收器的方法(来自嵌入类型)。
如果我们嵌入一个指针类型,非指针嵌入器的方法集将获取具有指针和非指针接收器的方法(来自嵌入类型)。
如果我们使用指向嵌入器的指针值,则无论嵌入类型是否是指针,指向嵌入器的指针的方法集始终都会获取具有指针和非指针接收器的方法(从嵌入类型)。
注意:
有一个非常相似的情况,即当您有一个包含 mytype
值的接口值时,并且您尝试 类型断言 另一个接口值,stringer
。在这种情况下,由于上述原因,断言将不成立,但我们会得到一个略有不同的运行时错误:
m := mytype{value: "something"} var i interface{} = m fmt.println(i.(stringer))
运行时恐慌(在 go playground 上尝试一下):
panic: interface conversion: main.mytype is not main.stringer: missing method string
尝试转换而不是类型断言,我们得到了我们正在讨论的编译时错误:
m := MyType{value: "something"} fmt.Println(Stringer(m))
Atas ialah kandungan terperinci X tidak melaksanakan Y (...kaedah mempunyai penerima penunjuk). Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!