结构是否实现了其嵌入类型之一实现的所有接口?

我有这个例子


// embed project main.go

package main


import (

    "fmt"

)


type A struct {

    A1 int

    A2 int

}


func (a A) Incr() int {

    a.A1++

    return a.A1

}


type B struct {

    A

    D int

}


type C interface {

    Incr() int

}


func Add(c C) {

    d := c.Incr()

    fmt.Println(d)

}


func main() {

    var s B

    s.Incr() //B has Incr

    Add(s)

}

使用这个例子,我想检查 B 是否实现了接口 C。在本例中,添加 accept s(类型 B)作为输入。B 实施 C .


但是当我将 Incr() 方法从原始更改为


func (a *A) Incr() int {

    a.A1++

    return a.A1

}

它编译器给出了错误


./main.go:35:不能在 AddContent 的参数中使用 s(类型 B)作为类型 C:B 没有实现 C(Incr 方法有指针接收器)


所以我仍然很困惑一个结构是否实现了它们的一个嵌入类型实现的所有接口。


catspeake
浏览 177回答 2
2回答

守着星空守着你

如果 S 包含匿名字段 T,则 S 和 *S 的方法集都包含接收者 T 的提升方法。 *S 的方法集还包括接收者 *T 的提升方法。如果 S 包含匿名字段 *T,则 S 和 *S 的方法集都包含带有接收者 T 或 *T 的提升方法。B 嵌入 A,因此 B 的方法集包括带有接收器 A 的原型方法,但不包括 *A

慕村9548890

是的,您的结构实现了嵌入类型的方法集。但是,当您更改Incrto的签名时func (a *A) Incr() int,您需要一个指向该方法接收者的指针。当它有一个指针接收器时,它A本身不会实现Incr。s.Incr()调用起作用的原因是该s值是可寻址的,并且 Go 会自动为方法调用引用它。当您传递s到 时Add,您试图将其转换为C接口,该值将不再可寻址,并且该Incr方法不在方法集中。在这种情况下,您可以将嵌入类型更改为*A,type B struct {     *A     D int}取s电话地点的地址Add(&s)或制作s一个指针 ( *B):s := &B{} Add(s)规范的相关部分给定一个结构类型 S 和一个名为 T 的类型,提升的方法包含在结构的方法集中,如下所示:如果 S 包含匿名字段 T,则 S 和 *S 的方法集都包含接收者 T 的提升方法。 *S 的方法集还包括接收者 *T 的提升方法。如果 S 包含匿名字段 *T,则 S 和 *S 的方法集都包含带有接收者 T 或 *T 的提升方法。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go