Golang Interfaces Tutorial with Examples for Developers

Golang Interfaces Tutorial with Examples for Developers

If you are new to Go language then, you may be heard or seen in the code about interface{} a lot in code snippets and tutorials. This can be very daunting seeing this at first. Interface implementation is one of the core concepts of Object-oriented programming language. If you have used Java, PHP, or Python then you might know what interface is and how it can be useful to build a scalable application.

Go Interface

An interface in Go is a type defined using a set of method signatures. The interface defines the behavior for similar type of objects.

For example, Here is an interface that defines the behavior for Geometrical shapes:

// Go Interface - `Shape`
type Shape interface {
    Area() float64
    Perimeter() float64
}

An interface is declared using the type keyword, followed by the name of the interface and the keyword interface. Then, we specify a set of method signatures inside curly braces.

Implementing an interface in Go

To implement an interface, you just need to implement all the methods declared in the interface.

Go Interfaces are implemented implicitly

Unlike other languages like Java, you don’t need to explicitly specify that a type implements an interface using something like an implements keyword.

Here are two Struct types that implement the Shape interface:

// Struct type `Rectangle` - implements the `Shape` interface by implementing all its methods.
type Rectangle struct {
    Length, Width float64
}

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

func (r Rectangle) Perimeter() float64 {
    return 2 * (r.Length + r.Width)
}
// Struct type `Circle` - implements the `Shape` interface by implementing all its methods.
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 (c Circle) Diameter() float64 {
    return 2 * c.Radius
}

Using an interface type with concrete values

An interface in itself is not that useful unless we use it with a concrete type that implements all its methods.

Let’s see how an interface can be used with concrete values.

  • An interface type can hold any value that implements all its methods

package main

import (
    "fmt"
    "math"
)

func main() {
    var s Shape = Circle{5.0}
    fmt.Printf("Shape Type = %T, Shape Value = %v\n", s, s)
    fmt.Printf("Area = %f, Perimeter = %f\n\n", s.Area(), s.Perimeter())

    var s1 Shape = Rectangle{4.0, 6.0}
    fmt.Printf("Shape Type = %T, Shape Value = %v\n", s1, s1)
    fmt.Printf("Area = %f, Perimeter = %f\n", s1.Area(), s1.Perimeter())
}


# Output
Shape Type = main.Circle, Shape Value = {5}
Area = 78.539816, Perimeter = 31.415927

Shape Type = main.Rectangle, Shape Value = {4 6}
Area = 24.000000, Perimeter = 20.000000
  • Using Interface types as arguments to functions
package main

import (
    "fmt"
)

// Generic function to calculate the total area of multiple shapes of different types
func CalculateTotalArea(shapes ...Shape) float64 {
    totalArea := 0.0
    for _, s := range shapes {
        totalArea += s.Area()
    }
    return totalArea
}

func main() {
    totalArea := CalculateTotalArea(Circle{2}, Rectangle{4, 5}, Circle{10})
    fmt.Println("Total area = ", totalArea)
}


# Output
Total area =  346.7256359733385
  • Using Interface types as fields
package main

import (
    "fmt"
)

// Interface types can also be used as fields
type MyDrawing struct {
    shapes  []Shape
    bgColor string
    fgColor string
}

func (drawing MyDrawing) Area() float64 {
    totalArea := 0.0
    for _, s := range drawing.shapes {
        totalArea += s.Area()
    }
    return totalArea        
}

func main() {
    drawing := MyDrawing{
        shapes: []Shape{
            Circle{2},
            Rectangle{3, 5},
            Rectangle{4, 7},
        },
        bgColor: "red",
        fgColor: "white",
    }

    fmt.Println("Drawing", drawing)
    fmt.Println("Drawing Area = ", drawing.Area())
}


# Output
Drawing {[{2} {3 5} {4 7}] red white}
Drawing Area = 55.56637061435917

Interface values: How does an interface type work with concrete values?

Under the hood, an interface value can be thought of as a tuple consisting of a value and a concrete type:

// interface
(value, type)

Let’s see an example to understand more:


package main

import (
    "fmt"
)

func main() {
    var s Shape

    s = Circle{5}
    fmt.Printf("(%v, %T)\n", s, s)
    fmt.Printf("Shape area = %v\n", s.Area())

    s = Rectangle{4, 7}
    fmt.Printf("(%v, %T)\n", s, s)
    fmt.Printf("Shape area = %v\n", s.Area())
}

# Output
({5}, main.Circle)
Shape area = 78.53981633974483
({4 7}, main.Rectangle)
Shape area = 28

Checkout the output of the above program and notice how the variable s has information about the value as well as the type of the Shape that is assigned to it.

When we call a method on an interface value, a method of the same name on its underlying type is executed.

For example, in the above program, when we call the method Area() on the variable s, it executes the Area() method of its underlying type.

go golang

Bootstrap 5 Complete Course with Examples

Bootstrap 5 Tutorial - Bootstrap 5 Crash Course for Beginners

Nest.JS Tutorial for Beginners

Hello Vue 3: A First Look at Vue 3 and the Composition API

Building a simple Applications with Vue 3

Deno Crash Course: Explore Deno and Create a full REST API with Deno

How to Build a Real-time Chat App with Deno and WebSockets

Convert HTML to Markdown Online

HTML entity encoder decoder Online

What's new in the go 1.15

Go announced Go 1.15 version on 11 Aug 2020. Highlighted updates and features include Substantial improvements to the Go linker, Improved allocation for small objects at high core counts, X.509 CommonName deprecation, GOPROXY supports skipping proxies that return errors, New embedded tzdata package, Several Core Library improvements and more.

Go Tutorial (Golang) - Looping Constructs in Golang | Golang For Loop

In this video we will see the Looping Constructs in Golang. Golang For Loop. Go is an open source programming language which was originally developed by Google. In this Go Tutorial we will Learn Go from the Basics with Code Examples. Go is a statically-typed language.

Golang Array Example | Arrays in Go Tutorial Explained

Golang array is a fixed-size collection of items of the same type. The items of an array are stored sequentially and can be accessed using their index.

Go Tutorial (Golang) 18 - tags in Golang | How To Use Struct Tags in Go

Go struct tags are annotations that are shown after the type in a Go struct declaration. Golang tag for a field allows us to attach meta-information to the field which we can acquire using reflection

Go Tutorial (Golang) - Looping Constructs in Golang | For Range loop in Golang

In this video we will see the Looping Constructs in Golang - Golang For for-range Loop. o is an open source programming language which was originally developed by Google. In this Go Tutorial we will Learn Go from the Basics with Code Examples. Go is a statically-typed language. Go has a syntax similar to C. Go has built-in concurrency.