Interfaces

Interface is a type and defines methods

func main() {
    // Here ConsoleWriter implements Writer interface
    // So we can define type of w as Writer and assign it ConsoleWriter
    var w Writer = ConsoleWriter{}
    w.Write([]byte("Hello there"))
}

type Writer interface {
    Write([]byte) (int, error)
}

type ConsoleWriter struct{}

func (c ConsoleWriter) Write(data []byte) (int, error) {
    n, err := fmt.Println(string(data))
    return n, err
}

Any type can implement interface

func main() {
    myInc := IntCounter(0)
    var inc Incrementer = &myInc

    for i := 0; i < 10; i++ {
        fmt.Println(inc.Increment())
    }
}

type Incrementer interface {
    Increment() int
}

type IntCounter int

func (i *IntCounter) Increment() int {
    *i++
    return int(*i)
}

Interfaces can be composed (just like structs)

type Writer interface {
    Write([]byte) (int, error)
}

type Closer interface {
    Close() error
}

type WriteCloser interface {
    Writer
    Closer
}

Type conversion

var wc WriterCloser = NewBufferedWriterCloser()
bwc := wc.(*BufferedWriterCloser)

// On type conversion, there can be second parameter that signals about operation success otherwise panic occur if type conversion failed
if bwc, ok := wc.(*BufferedWriterCloser); ok {
    // do something with bwc
}

Every type in go implements empty interface var i interface{} = 0