Implementing interfaces
April 12, 2023
Basic interfaces
…
More than one type may implement an interface. For instance, if two types
S1
andS2
have the method setfunc (p T) Read(p []byte) (n int, err error) func (p T) Write(p []byte) (n int, err error) func (p T) Close() error
(where
T
stands for eitherS1
orS2
) then the File interface is implemented by bothS1
andS2
, regardless of what other methodsS1
andS2
may have or share.
This is the formal definition of Go’s version of Duck typing, which we’ve already discussed.
The explanation continues…
Every type that is a member of the type set of an interface implements that interface. Any given type may implement several distinct interfaces. For instance, all types implement the empty interface which stands for the set of all (non-interface) types:
interface{}
For convenience, the predeclared type
any
is an alias for the empty interface.
It’s not always obvious which types implement a given interface, and this can trip up many newcomers. Some IDEs will let you find types that implement a given interface, but for some common interfaces this is next to worthless. Consider perhaps the most common interface type, the io.Reader
. There are dozens of implementations of this interface in the standard library alone. Likely hundreds or thousands in any reasonably sized project.
And most types don’t overtly advertise that they satisfy any particular interface. Consider the os.File
type. This type has a number of methods defined on it: Close() error
, Chdir() error
, Name() string
, Read([]byte) (int, error)
, and many others.
But what interfaces does it implement? Well, several, actually. It’s an io.Reader
by virtue of implementing the Read()
method. It’s also an io.ReadCloser
because it implements both the Read()
method and the Close()
method. It’s also a an io.Writer
and io.WriteCloser
, and even a io.ReadWriteCloser
, and many others. It can even implement user-defined interfaces. Do you want a ChdirReader
interface?
type ChdirReader interface {
Chdir() error
Read([]byte) (int, error)
}
Fine, create that type, and os.File
will automatically implement it, because it has those methods.
Quotes from The Go Programming Language Specification Version of December 15, 2022