我有这个例子
// 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.在此示例中,添加接受s(类型B)作为输入。 B实施C 。
但是当我将Incr()方法从原始改为
时func (a *A) Incr() int {
a.A1++
return a.A1
}
它编译器给出了错误
./ main.go:35:不能在参数中使用s(类型B)作为类型C. AddContent:B没有实现C(Incr方法有指针接收器)
所以我仍然困惑一个结构是否实现了其嵌入式类型之一的所有接口。
答案 0 :(得分:2)
如果S包含匿名字段T,则S和* S的方法集都包括带有接收方T的提升方法。* S的方法集还包括带接收方* T的提升方法。
如果S包含匿名字段* T,则S和* S的方法集都包含 用接收者T或* T推广方法。
B嵌入A,因此B的方法集包括带接收器A的启动方法,但不包括* A
答案 1 :(得分:2)
是的,你的struct实现了嵌入式的方法集。
但是,当您将Incr
的签名更改为func (a *A) Incr() int
时,您需要一个指针用于该方法的接收者。 <{1}}本身在有指针接收器时不会实现A
。
Incr
调用的作用原因是s.Incr()
值是可寻址的,并且Go会自动引用它以进行方法调用。当您将s
传递给s
时,您尝试将其转换为Add
界面,该值将不再可寻址,并且C
方法不会在方法集中。
在这种情况下,您可以将嵌入类型更改为Incr
,
*A
在呼叫站点获取type B struct {
*A
D int
}
的地址
s
或使Add(&s)
指针(s
):
*B
给定结构类型S和名为T的类型,提升的方法是 包含在结构的方法集中,如下所示:
- 如果S包含匿名字段T,则S和* S的方法集都包括带有接收者T的提升方法。* S的方法集也 包括带接收器* T的推广方法。
- 如果S包含匿名字段* T,则S和* S的方法集都包括带有接收者T或* T的提升方法。