Working with Interfaces in Go

11.17.2021

Intro

Interfaces in Go work a bit different than in other languages. First of all, you specify only the methods that an interface should conform to and not the properties. Also, interfaces are implicit rather than explicitly. In this article, we will learn how to use Go interfaces.

Declare Interface

To create an interface, we define a type and use the interface keyword. Here is an example of defining a Shape interface with a area method. We want all other shapes to implement this method.

type Shape interface {
    area() float64
}

To implement a interface, we declare a type, here we use a struct, and then we declare methods with type receivers to implement the interface. Here is a circle for example. Here you can see we don't explicitly implement the interface, but the go compiler infers this from the method definitions.

type Circle struct {
   x float64
   y float64
   radius float64
}

Then we add the area method.

func (circle Circle) area() float64 {
   return math.Pi * circle.radius * circle.radius
}

In a similar way, let's create a Rectangle that implements the interface.

type Rectangle struct {
   width float64
   height float64
}

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

Now, let's see how this works together.

func main() {
   circle := Circle{ x: 0, y: 0, radius: 5 }
   fmt.Println(circle.area())

   rectangle := Rectangle{ width: 10, height: 5 }
   fmt.Println(rectangle.area())
}

To see the interface in action, let's create a function that requires a Shape type, but not a Circle or Rectangle. When we pass our instances to this function, Go will check if the type conforms to the interface.

func getArea(shape Shape) float64 {
   return shape.area()
}

func main() {
   circle := Circle{ x: 0, y: 0, radius: 5 }
   fmt.Println(getArea(circle))

   rectangle := Rectangle{ width: 10, height: 5 }
   fmt.Println(getArea(rectangle))
}

Full Example

You can run the full example code by copying the code below to a file called main.go and run go run main.go

package main

import (
	"fmt"
	"math"
)

type Shape interface {
	area() float64
}

type Circle struct {
	x      float64
	y      float64
	radius float64
}

func (circle Circle) area() float64 {
	return math.Pi * circle.radius * circle.radius
}

type Rectangle struct {
	width  float64
	height float64
}

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

func getArea(shape Shape) float64 {
	return shape.area()
}

func main() {
	circle := Circle{x: 0, y: 0, radius: 5}
	fmt.Println(getArea(circle))

	rectangle := Rectangle{width: 10, height: 5}
	fmt.Println(getArea(rectangle))
}