UP | HOME

Go: Interfaces

Table of Contents

1 Interfaces

An interface type is defined by a set of methods. A value of interface type can hold any value that implements those methods. This time we made the greeting feature more generic by defining a function called Greet which takes a param of interface type Namer. Namer is a new interface we defined which only defines one method: Name(). So Greet() will accept as param any value which has a Name() method defined.

package main

import (
        "fmt"
        "os"
)

type User struct {
        FirstName, LastName string
}

func (u *User) Name() string {
        return fmt.Sprintf("%s %s", u.FirstName, u.LastName)
}

type Namer interface {
        Name() string
}

func Greet(n Namer) string {
        return fmt.Sprintf("Dear %s", n.Name())
}

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

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

type ReadWriter interface {
        Reader
        Writer
}

func main() {
        u := &User{"Pavel", "Vavilin"}
        fmt.Println(Greet(u))

        var w Writer
        // os.Stdout implements Writer
        w = os.Stdout
        fmt.Fprintf(w, "hello, writer\n")
}
Dear Pavel Vavilin
hello, writer

The Go convention for interface names is that they should end wiht er

2 Errors

An error is anything that can describe itself as an error string. The idea is captured by the predefined, built-in interface type, error, with its single method, Error, returning a string:

type error interface {
        Error() string
}

The fmt package’s various print routines automatically know to call the method when asked to print an error.

package main

import (
        "fmt"
        "time"
)

type MyError struct {
        When time.Time
        What string
}

func (e *MyError) Error() string {
        return fmt.Sprintf("at %v, %s", e.When, e.What)
}

func run() error {
        return &MyError{
                time.Now(),
                "it didn't work",
        }
}

func main() {
        if err := run(); err != nil {
                fmt.Println(err)
        }
}
at 2017-12-12 00:36:21.148564468 +0500 +05, it didn't work

Author: Pavel Vavilin

Created: 2017-12-12 Tue 00:36

Validate