Anonymous/explicitly embedded a interface in struct

Viewed 231
type A interface {
    f()
}

type B struct {
    A
}

type C struct {
    Imp A
}

func main() {
    b := B{}
    c := C{}
    //b can be directly assigned to the A interface, but c prompts that it cannot be assigned
    var ab A = b
    //Cannot use 'c' (type C) as type A in assignment Type does not implement 'A' as some methods are missing: f() 
    var ac A = c
}

what's the different between in the B struct and C struct?

in Go sheet

A field declared with a type but no explicit field name is called an embedded field. An embedded field must be specified as a type name T or as a pointer to a non-interface type name *T, and T itself may not be a pointer type. The unqualified type name acts as the field name.

1 Answers

If you continue reading the same section of the spec of the spec, you will notice the following:

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

  • If S contains an embedded 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 embedded field *T, the method sets of S and *S both include promoted methods with receiver T or *T.

Your struct B has no methods explicitly defined on it, but B's method set implicitly includes the promoted methods from the embedded field. In this case, the embedded field is an interface with method f(). You can use any object that satisfies that interface and its f() method will automatically be part of the method set for B.

On the other hand, your C struct has a named field. The methods on Imp do not get automatically added to C's method set. Instead, to access the f() method from Imp, you would need to specifically call C.Imp.f().

Finally: the fact that you're using an interface as the (embedded or not) field does not matter, it could easily be another struct that has a f() method. The important part is whether f() becomes part of the parent struct's method set or not, which will allow it to implement A or not.

Related