Go Interface

Summary: in this tutorial, you will learn how to use the Go interface to write functions that accept different types that implement the same interface.

In Go, an interface is a type that specifies a set of method signatures. This means that the methods you specify in the interfaces do not have implementations.

Defining an interface

Here’s the syntax for defining an interface in Go:

type InterfaceName interface {
   method1(parameters) returnType1
   method2(parameters) returnType2
   ...
}Code language: Go (go)

In this syntax:

  • First, specify the type, interface name, and the interface keyword.
  • Second, list one or more methods within the curly braces.

For example, the following defines an interface named Shape:

type Shape interface {
    Area() float64
    Perimeter() float64
}Code language: Go (go)

The Shape interface has two methods Area() and Perimeter() that accepts no parameters and returns a float64 value.

Implementing an interface

To implement an interface, you provide the type with implementations of the methods defined in the interface.

For example, the following defines the Rectangle struct type that implements the Shape interface:

type Rectangle struct {
    Width, Length float64
}

func (r Rectangle) Area() float64 {
    return r.Width * r.Length
}

func (r Rectangle) Perimeter() float64 {
    return 2 * (r.Width + r.Length)
}Code language: Go (go)

Since the Rectangle struct implements the Shape interface, you can use it anywhere that accepts the Shape interface type.

Using the interface

The following defines a function that accepts a slice of Shape interfaces:

func calculateTotalArea(shapes []Shape) float64 {
    var totalArea float64
    for _, s := range shapes {
        totalArea += s.Area()
    }
    return totalArea
}Code language: Go (go)

Since the Rectangle implements the Shape interface, you can pass it to the calculateTotalArea function:

package main

import "fmt"

type Shape interface {
    Area() float64
    Perimeter() float64
}

type Rectangle struct {
    Width, Length float64
}

func (r Rectangle) Area() float64 {
    return r.Width * r.Length
}

func (r Rectangle) Perimeter() float64 {
    return 2 * (r.Width + r.Length)
}

func calculateTotalArea(shapes []Shape) float64 {
    var totalArea float64
    for _, s := range shapes {
        totalArea += s.Area()
    }
    return totalArea
}

func main() {
    shapes := []Shape{
        Rectangle{Width: 5, Length: 10},
        Rectangle{Width: 3, Length: 5},
    }

    fmt.Printf("Total area: %.2f\n", calculateTotalArea(shapes))
}Code language: Go (go)

Output:

Total area: 65.00Code language: Go (go)

Adding more types that implement the same interface

The following defines the Circle struct type that implements the Shape interface:

type Circle struct {
    Radius float64
}

func (c Circle) Area() float64 {
    return math.Pi * c.Radius * c.Radius
}

func (c Circle) Perimeter() float64 {
    return 2 * math.Pi * c.Radius
}Code language: Go (go)

Since Circle implements the Shape interface, it is a Shape. We can also use the Circle as a Shape. For example:

func main() {
    shapes := []Shape{
        Rectangle{Width: 5, Length: 10},
        Rectangle{Width: 3, Length: 5},
        Circle{Radius: 10},
    }

    fmt.Printf("Total area: %.2f\n", calculateTotalArea(shapes))
}Code language: Go (go)

Output:

Total area: 379.16Code language: Go (go)

Here’s the complete program:

package main

import (
    "fmt"
    "math"
)

type Shape interface {
    Area() float64
    Perimeter() float64
}

type Rectangle struct {
    Width, Length float64
}

func (r Rectangle) Area() float64 {
    return r.Width * r.Length
}

func (r Rectangle) Perimeter() float64 {
    return 2 * (r.Width + r.Length)
}

func calculateTotalArea(shapes []Shape) float64 {
    var totalArea float64
    for _, s := range shapes {
        totalArea += s.Area()
    }
    return totalArea
}

type Circle struct {
    Radius float64
}

func (c Circle) Area() float64 {
    return math.Pi * c.Radius * c.Radius
}

func (c Circle) Perimeter() float64 {
    return 2 * math.Pi * c.Radius
}

func main() {
    shapes := []Shape{
        Rectangle{Width: 5, Length: 10},
        Rectangle{Width: 3, Length: 5},
        Circle{Radius: 10},
    }
    fmt.Printf("Total area: %.2f\n", calculateTotalArea(shapes))
}Code language: Go (go)

Interfaces allow you to write functions that accept different types as long as they implement the same interface.

Summary

  • An interface is a type that includes a set of method signatures.
  • To implement an interface, define methods specified in the interface for the type.
  • An interface allows you to write code that accepts different types as long as they have the same interface.
Was this tutorial helpful?