An interface defines a set of methods on a type.

Interfaces are used to abstract behavior.

For example: a standard library defines io.Reader interface:

type Reader interface {
    Read(d []byte) (int, error)
}

Most functions that operate on streams of binary data (e.g. json decoder) take io.Reader as a source of data. That way we can implement Reader interface for physical files, bytes in memory, network connections and have json.Decode work on all those sources.

Here’s how to define and implement a simple interface:

https://codeeval.dev/gist/07b87878ae9efeb2478a52f437a33d40

Unlike most other languages, interfaces are satisfied implicitly.

We don’t have to explicitly declare that struct User implements interface Stringer.

Interfaces can only contain methods, not data. You can use struct embedding if you want to re-use both methods and data.

You can only define methods on types defined in the same package. We had to define type alias MyInt because we can’t add methods to built-int type int.

Simple interface

Determining underlying type from interface

Ensure that type implements interface