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

I have this example

// 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)
}

Using this example i wanted to check whether B implement interface C or not. In this example Add accept s (type B) as input. B implement C.

But when i change Incr() method from original to

func (a *A) Incr() int {
    a.A1++
    return a.A1
}

It compiler gives the error

./main.go:35: cannot use s (type B) as type C in argument to AddContent: B does not implement C (Incr method has pointer receiver)

So i am still confused whether a struct implement all the interface that one of their embedded type implement.

Yes, your struct implements the method set of the embedded type.

However, when you change the signature of Incr to func (a *A) Incr() int, you need a pointer for the receiver of that method. A itself doesn't implement Incr when it has a pointer receiver.

The reason the s.Incr() call works, is that the s value is addressable, and Go automatically references it for the method call. When you pass s to Add, you're attempting to convert it to a C interface, the value would no longer be addressable, and the Incr method isn't in the method set.

In this case, you can either change the embedded type to *A,

type B struct {
    *A
    D int
}

take the address of s at the call site

Add(&s)

or make s a pointer (*B):

s := &B{}
Add(s)

The relevent portion of the spec

Given a struct type S and a type named T, promoted methods are included in the method set of the struct as follows:

  • If S contains an anonymous field T, the method sets of S and *S both include promoted methods with receiver T. The method set of *S also includes promoted methods with receiver *T.
  • If S contains an anonymous field *T, the method sets of S and *S both include promoted methods with receiver T or *T.

If S contains an anonymous field T, the method sets of S and *S both include promoted methods with receiver T. The method set of *S also includes promoted methods with receiver *T.

If S contains an anonymous field *T, the method sets of S and *S both include promoted methods with receiver T or *T.

B embedded A, so method sets of B include protomoted methods with receiver A, but does not include *A