How I Stopped Worrying and Learned to Love Go Interfaces
Allan Githaiga

Allan Githaiga @githaiga22

About: Founder Imara | Blockchain Developer | Full-stack Dev at Zone01 Kisumu | 4x winner in Blockchain Hackathons | Proficient in Golang & Rust

Location:
Kenya
Joined:
May 24, 2024

How I Stopped Worrying and Learned to Love Go Interfaces

Publish Date: Oct 23 '24
88 19

Hey there, fellow Go newbies (or should I say Gophers-in-training🕧)! 🌱
Interfaces seemed like one of those mysterious, magical things that everyone kept talking about but no one really explained in a way that made sense. “It’s like polymorphism but simpler,” they said. “It’s just like a contract,” they claimed. But every time I tried to implement one, my code would look at me like, "What are you even doing, human?" 👀

But that was then. Now, interfaces and I are on much better terms, and I'm here to help you avoid my early confusion. So, if you’ve been scratching your head about Go interfaces, grab a cup of coffee (or tea), and let’s break it down, one step at a time—minus the headaches. 💡
So, What Exactly Is an Interface?

Let’s start from the very top. In Go, an interface is basically a way to define behavior, but without getting bogged down by the details of how it works. Imagine you’re the boss of a factory, and you don’t care how the machine works; you just care that it can produce the product. That’s what Go interfaces are like: you define what needs to happen, but not how it should be done.

For example, let’s pretend we’re working with animals (yes, Go works with animals, stay with me here). You know every animal makes a sound, but you don’t really care how that happens. Dogs bark, cats meow, and ducks…well, they quack. You can define an interface like this:

type Animal interface {
    Sound() string
}

Enter fullscreen mode Exit fullscreen mode

What’s this?
What’s this? Just a contract, saying: "Hey, any type that wants to be called an Animal must have a Sound() method." That’s it! No weird wizardry involved.

Show Me the Code! 🐶🐱🦆

Let’s take a super simple example and see how it works in action. We’ll create some animals and make them speak.

package main

import "fmt"

// The Animal interface
type Animal interface {
    Sound() string
}

// Define a Dog
type Dog struct{}

func (d Dog) Sound() string {
    return "Woof!"
}

// Define a Cat
type Cat struct{}

func (c Cat) Sound() string {
    return "Meow!"
}

func main() {
    // Our Animal variable can hold any type that satisfies the interface
    var myPet Animal

    // myPet is now a Dog
    myPet = Dog{}
    fmt.Println(myPet.Sound())  // Outputs: Woof!

    // myPet is now a Cat
    myPet = Cat{}
    fmt.Println(myPet.Sound())  // Outputs: Meow!
}

Enter fullscreen mode Exit fullscreen mode

What’s happening here?

  1. We define an Animal interface that has one method: Sound() 🔊.
  2. Then we create two types, Dog and Cat, and give them their unique Sound() methods.
  3. In the main() function, we create a variable myPet that can hold anything that satisfies the Animal interface.
  4. First, we assign a Dog, and boom! Our dog barks: "Woof!" 🐕
  5. Then we assign a Cat, and guess what? It meows: "Meow!" 🐈

Here’s where the magic of Go interfaces really kicks in 🔥🔥:
as long as a type has the required method, it satisfies the interface. No need to explicitly say "Dog implements Animal"—Go is smart enough to figure it out on its own! 🧠💡

Why Should You Care About Interfaces?

why should i care
Let me level with you. At first, I was like, “Why even bother with this? I can just write my methods directly!” But trust me, you’ll want to understand interfaces sooner rather than later, especially when your codebase starts to grow.

Here’s why:

  1. Flexibility: Interfaces make your code more flexible. You can swap out one type for another as long as it satisfies the interface. It’s like hiring someone based on their skills rather than their job title.
  2. Polymorphism: You can treat different types uniformly if they implement the same interface. This is what makes interfaces so powerful—it’s like having a universal remote that works with any TV.

  3. Clean Code: Interfaces allow you to write cleaner, more modular code. You define behaviors and let the types handle their own implementation.

Multiple Methods, No Problem!

Let’s kick it up a notch. Say you’re building a system to work with shapes, and you want to calculate both area and perimeter for different shapes like circles and rectangles. Enter the multi-method interface!

package main

import "fmt"

// Shape interface with two methods
type Shape interface {
    Area() float64
    Perimeter() float64
}

// Rectangle struct
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 + r.Height)
}

// Circle struct
type Circle struct {
    Radius float64
}

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

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

func main() {
    var shape Shape

    shape = Rectangle{Width: 5, Height: 4}
    fmt.Println("Rectangle Area:", shape.Area())           // Outputs: 20
    fmt.Println("Rectangle Perimeter:", shape.Perimeter()) // Outputs: 18

    shape = Circle{Radius: 3}
    fmt.Println("Circle Area:", shape.Area())           // Outputs: 28.26
    fmt.Println("Circle Perimeter:", shape.Perimeter()) // Outputs: 18.84
}

Enter fullscreen mode Exit fullscreen mode

The Empty Interface (interface{})

Oh, you thought we were done?😂😂😂 Nope! Let’s go a bit deeper with the empty interface, interface{}, which is Go’s way of saying, “I can hold any type.” It’s like a free-for-all box where you can throw in anything—strings, numbers, structs—you name it.

package main

import "fmt"

func PrintAnything(val interface{}) {
    fmt.Println(val)
}

func main() {
    PrintAnything("Hello, Gophers!") // Outputs: Hello, Gophers!
    PrintAnything(42)                // Outputs: 42
    PrintAnything(true)              // Outputs: true
}

Enter fullscreen mode Exit fullscreen mode

The empty interface is often used in situations where you don’t know ahead of time what type you’ll be dealing with (think APIs or libraries). It’s like Go’s version of a wildcard.

Embrace the Interface

Learning Go interfaces can feel like navigating a labyrinth at first, but once you grasp the basics, it opens up a whole new world of flexible, reusable, and clean code. So don’t be afraid to dive in!

Start simple, play with small examples, and let Go’s interface magic grow on you. Before long, you’ll be writing code that’s as clean and flexible as a yoga instructor at a tech conference.

Happy coding, fellow Gophers! May your interfaces be simple, and your structs be ever-implementing. 😄✌️

am done

Comments 19 total

  • Fred
    FredOct 23, 2024

    great article @githaiga22 , this is a nice and fun way to explain interfaces.

  • Stanley Kariuki
    Stanley Kariuki Oct 24, 2024

    If I may ask how do you make your blog banners especially the Go character?

    • Allan Githaiga
      Allan GithaigaOct 24, 2024

      well i just modify them using UX tools like figma,miro or canva

  • Victor Paul Arony
    Victor Paul AronyOct 24, 2024

    nice learning interface and struct diffrances

  • Lamine
    LamineOct 24, 2024

    Salut à tous.
    Je suis développeur d'application Android et je viens juste de terminer mon application gratuite de philosophie.
    J'aimerais avoir des testeurs pour m'aider à l'améliorer. Voici mon adresse mail :
    Laminefalldeveloppeur@gmail.com

  • Nikita N
    Nikita NOct 25, 2024

    This article is one of the most useful I've read recently about GoLang, especially regarding interfaces. Thank you!

  • Martin Baun
    Martin BaunOct 25, 2024

    Go makes me love my job :)

    • Allan Githaiga
      Allan GithaigaOct 25, 2024

      Hey martin..indeed Go is the best language so far to work with especially while focusing on the back-end side..Looking foward to collaborate with you in any kind of projects you need assistance
      reach me out thru my email : allangithaiga5@gmail.com
      Best regards,
      Allan Githaiga

      • David Sugar
        David SugarOct 26, 2024

        This is true for services development in general, not just web backends, and those issues I used to find vexing (vendor caching, for offline builds, for example) are now long gone. It remains clean to read with long term stability in the compiler and ecosystem, so you don't have things constantly change and break every time you happen to do a newer build...

  • Pallavi Godse
    Pallavi GodseOct 25, 2024

    I too worry too much when working in Go. Thank you for this guide!

  • Oscar
    OscarOct 25, 2024

    Just a heads up that you can add highlighting to the code blocks if you'd like. Just change:

    code block with no colors example

    ... to specify the language:

    code block with colors example

    More details in our editor guide!

  • Denil
    DenilOct 26, 2024

    Nice article, straight to the point.

  • АнонимNov 2, 2024

    [hidden by post author]

  • АнонимNov 3, 2024

    [hidden by post author]

  • Mi113r
    Mi113rDec 5, 2024

    All articles at this level, don't answer the question
    “Why not use the original structure ?”

     shape = Rectangle{Width: 5, Height: 4}
      fmt.Println("Rectangle Area:", shape.Area())           // Outputs: 20
      fmt.Println("Rectangle Perimeter:", shape.Perimeter()) // Outputs: 18
    
     // Ok, its similar ?
     rectangle := Rectangle{Width: 5, Height: 4}
        fmt.Println("Rectangle Area:", rectangle .Area())           // Outputs: 20
        fmt.Println("Rectangle Perimeter:", rectangle .Perimeter()) // Outputs: 18
    
    // why i need use interface ?
    
    Enter fullscreen mode Exit fullscreen mode
    • Sasho Ristevski
      Sasho RistevskiDec 5, 2024

      If you don't use an interface, you'd end up duplicating a lot of the same methods (like Area() and Perimeter()) across different structs. The benefit of the interface comes when you need to handle a diverse range of shapes without constantly worrying about the details of each one.

  • prakash chokalingam
    prakash chokalingamDec 5, 2024

    Great article! Thanks for the explanation.

  • Sasho Ristevski
    Sasho RistevskiDec 5, 2024

    for the full explanation of the example above i find this useful
    youtube.com/watch?v=SX1gT5A9H-U

Add comment