freeCodeCamp/guide/english/go/go-interfaces/index.md

2.1 KiB

title
Go Interfaces

Go Interfaces

An interface in Go is a collection of methods. If a type can satisfy all methods in an interface then it is part of that interface.

Let's create a shape interface:

type shape interface {
  area() float64
  perimeter() float64
}

This interface has two methods area() and perimeter(). Now lets create a rectangle that satisfies this interface:

type rectangle struct {
  width, height float64
}

func (r rectangle) area() float64 {
  return r.width * r.height
}

func (r rectangle) perimeter() float64 {
  return 2*r.width + 2*r.height
}

This rectangle contains all the methods needed to be a shape. Lets add another circle:

type circle struct {
  radius float64
}

func (c circle) area() float64 {
  return math.Pi * c.radius * c.radius  // math.Pi is the Pi constant in the go math package
}

func (c circle) perimeter() float64 {
  return 2 * math.Pi * c.radius
}

Now we can create a function that prints out the information of any shape:

func shapeInfo(s shape) {
	fmt.Println(reflect.TypeOf(s)) // reflect.TypeOf(s) will return the type of shape
	fmt.Println(s.area())
	fmt.Println(s.perimeter())
}

Because both rectangle and circle satisfy the interface shape they can be used in the shapeInfo function:

func main() {
r := rectangle{width:5, height:10}
c := circle{radius: 12}

shapeInfo(r)
shapeInfo(c)
}

Here we called shapeInfor for both a type rectangle and a type cricle.

If we removed the perimeter method from the circle type we would get an error such as:

cannot use c (type circle) as type shape in argument to shapeInfo:
        circle does not implement shape (missing perimeter method)

The empty interface

The empty interface is a common tool used by Go programmers. An empty interface contains no methods and has the form:

interface{}

An empty interface can hold values of any type as every type implements atleast zero methods. This can be useful for designing functions where the input type is unknown.

func describe(i interface{}) {
  fmt.Printf("(%v, %T)\n", i, i) // Print the value and type of i
}