Embedded interfaces

April 17, 2023

Embedded interfaces

In a slightly more general form an interface T may use a (possibly qualified) interface type name E as an interface element. This is called embedding interface E in T. The type set of T is the intersection of the type sets defined by T’s explicitly declared methods and the type sets of T’s embedded interfaces. In other words, the type set of T is the set of all types that implement all the explicitly declared methods of T and also all the methods of E.

type Reader interface {
	Read(p []byte) (n int, err error)
	Close() error
}

type Writer interface {
	Write(p []byte) (n int, err error)
	Close() error
}

// ReadWriter's methods are Read, Write, and Close.
type ReadWriter interface {
	Reader  // includes methods of Reader in ReadWriter's method set
	Writer  // includes methods of Writer in ReadWriter's method set
}

When embedding interfaces, methods with the same names must have identical signatures.

type ReadCloser interface {
	Reader   // includes methods of Reader in ReadCloser's method set
	Close()  // illegal: signatures of Reader.Close and Close are different
}

Similar to the way structs may have embedded fields, interfaces can be embedded as well. Although there are a couple of key differences:

  • The name of the embedded interface has no bearing on the outter interface. With structs, the name of the embedded type becomes an implicit struct field name.
  • Methods of the same name must have identical signatures. With structs, the outter-most definition of a field takes precidence over any embedded field of the same name.

Quotes from The Go Programming Language Specification Version of December 15, 2022


Share this

Direct to your inbox, daily. I respect your privacy .

Unsure? Browse the archive .

Related Content


Illegal selectors

We’ll cover the last 3 rules of selectors in one go today, since they’re all about illegal selectors. Selectors … In all other cases, x.f is illegal. Simple enough. The cases mentioned in rules 1-3 ar ethe only valid uses of x.f. All others are illegal. var x int x.chicken // illegal! If x is of pointer type and has the value nil and x.f denotes a struct field, assigning to or evaluating x.


Defining method sets

Recall that every type in Go has a method set. Let’s examine how that’s defined: Method sets … Every type has a (possibly empty) method set associated with it: The method set of a defined type T consists of all methods declared with receiver type T. type S struct { /* Possibly some fields */ } // Foo() is a member of the method set of `S`, because it has a receiver type `S`.


Recursive interfaces

Check out this week’s episode of the Cup o’ Go podcast: What the ʕ◔ϖ◔ʔ? New merch, TDD book interview with Adelina Simion, and more You can probably guess Go’s rules about recursively embedding interfaces. In short: It’s not allowed. General interfaces … An interface type T may not embed a type element that is, contains, or embeds T, directly or indirectly. // illegal: Bad may not embed itself type Bad interface { Bad } // illegal: Bad1 may not embed itself using Bad2 type Bad1 interface { Bad2 } type Bad2 interface { Bad1 } // illegal: Bad3 may not embed a union containing Bad3 type Bad3 interface { ~int | ~string | Bad3 } // illegal: Bad4 may not embed an array containing Bad4 as element type type Bad4 interface { [10]Bad4 } Note however, that, an interface method may refer to the interface itself.

Get daily content like this in your inbox!

Subscribe