Skip to main content

Why Interfaces are Awesome in Go

golang interfaces

Why Interfaces are Awesome in Go Language

Go, or Golang, is known for being a simple, yet powerful programming language. One of the core concepts that makes Go stand out is interfaces. Interfaces in Go help you write flexible, reusable, and maintainable code. They allow different types to share common behaviors without worrying about the exact type behind the scenes.

In this article, we'll dive into why interfaces are awesome, with easy-to-understand examples. We’ll also give some tips on how to make the best use of them in your Go programs.

What is an Interface?

An interface in Go defines a set of method signatures (rules), but it doesn't provide the implementation. Instead, any type that implements these methods can be said to "satisfy" the interface. This allows you to write code that can work with different types as long as they share certain behaviors.

Basic Example of an Interface

package main

import "fmt"

// Define an interface with one method
type Speaker interface {
    Speak() string
}

// Define a type that implements the Speaker interface
type Dog struct{}

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

// Another type that implements the Speaker interface
type Cat struct{}

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

func main() {
    var animals []Speaker
    // Dog and Cat both implement the Speaker interface
    animals = append(animals, Dog{}, Cat{})
    for _, animal := range animals {
        fmt.Println(animal.Speak())
    }
}

In this example, we define a Speaker interface that requires a Speak() method. Both Dog and Cat implement this interface by providing their own versions of the Speak() method. When we loop through a slice of Speaker types, the correct Speak() method for each type is called.

This flexibility is what makes interfaces so powerful. You can handle multiple types without needing to know their exact types, as long as they implement the required behavior.

Why are Interfaces Awesome?

1. Encapsulation of Behavior

With interfaces, you can focus on behavior rather than specific types. In the example above, the Speaker interface doesn't care whether it's a Dog, Cat, or some other type. It only cares that the type knows how to Speak().

2. Flexibility

Interfaces let you write flexible code. You can add new types that satisfy the interface without changing existing code. This makes it easier to extend and maintain your programs.

For example, if you later decide to add a Bird type, it can easily be added to the animals list without changing anything else:

type Bird struct{}

func (b Bird) Speak() string {
    return "Chirp!"
}

Just add Bird{} to the slice of animals, and it works perfectly:

animals = append(animals, Bird{})

3. Loose Coupling

Interfaces allow you to decouple different parts of your code. The code using the interface doesn't need to know the details of the types that implement it. This leads to more modular code, which is easier to test and reuse.

Making Best Use of Interfaces

Now that we’ve seen why interfaces are great, let’s talk about how to use them effectively.

1. Design for Behavior, Not Data

When designing interfaces, focus on what the type should do, not how it stores data. Instead of thinking, "I need an interface for animals with legs," think, "I need an interface for things that can Speak()." This encourages flexible design and avoids overcomplicating your code.

2. Keep Interfaces Small

Go encourages small, focused interfaces. A good rule of thumb is to keep interfaces with just one or two methods. This makes them easier to implement and encourages composability.

Here’s a good example of small interfaces:

type Writer interface {
    Write(p []byte) (n int, err error)
}

type Reader interface {
    Read(p []byte) (n int, err error)
}

Both Writer and Reader interfaces have just one method, which makes them easy to implement. You can combine them in more complex interfaces when needed:

type ReadWriter interface {
    Reader
    Writer
}

3. Use Empty Interface with Caution

Go has an "empty" interface, interface{}, which can hold any type. This is sometimes useful, but it should be used sparingly. Overusing interface{} can lead to code that’s hard to understand and error-prone, because you lose the benefits of type safety.

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

While this works for any type, it's better to use specific interfaces or types whenever possible to keep your code clear and maintainable.

4. Use Type Assertions to Access Underlying Types

Sometimes, you might need to access the underlying type that implements an interface. You can do this using type assertions. Here's an example:

func SpeakLoudly(s Speaker) {
    fmt.Println(s.Speak())

    if dog, ok := s.(Dog); ok {
        fmt.Println("This is a dog, let's make it louder: WOOF!")
    }
}

func main() {
    SpeakLoudly(Dog{})
    SpeakLoudly(Cat{})
}

In this example, we use a type assertion (s.(Dog)) to check if the Speaker is of type Dog and handle it differently.

Conclusion

Interfaces are awesome in Go because they provide flexibility, loose coupling, and allow for clean, maintainable code. By focusing on behavior rather than concrete types, you can write code that works with a wide range of types, making it easier to extend and maintain over time.

To make the best use of interfaces in Go:

  • Design interfaces around behavior.
  • Keep them small and focused.
  • Avoid overusing the empty interface.
  • Use type assertions wisely when necessary.

By following these practices, you can make the most out of Go’s powerful interface system and write cleaner, more efficient code.

Happy coding! 🎉

Comments

Popular posts from this blog

Image Search Engine Using Python

Images provide a lot more information than audio or text. Image processing is the prime field of research for robotics as well as search engines. In this article we will explore the concept of finding similarity between digital images using python. Then we will use our program to find top 10 search results inside a dataset of images for a given picture. It won't be as good as google's search engine because of the technique we will be using to find similarity between images. But what we are going to make will be pretty cool. So lets start. Setting up the Environment Our Algorithm How the code looks Lets build the GUI Additional Techniques Setting up the Environment The code we are going to write requires a few tools which we need to install first. I will try to be as precise as i can and if you get stuck into installing some tool then you can drop a comment below and i will help you sort out the problem. So here are the tools and the steps to install

Understanding Python Decorators

If you have ever wondered what those @something mean above a python function or method then you are going to have your answers now. This @something line of code is actually called a decorator. I have red from various articles about them but some of them were not able to clarify the concept of a decorator and what we can achieve with them. So in this post we'll learn a lot about python decorators. Here is a list of topics we'll be covering. What is python decorator Understanding the concept Multiple decorators on same function class method decorator Where can we use decorators What is python decorator A python decorator is nothing but a function which accepts your given function as a parameter and returns a replacement function. So its like something this def decorator(your_func): def replacement(your_func_args): #do some other work return replacement @decorator your_func(your_func_args): #your_func code Now when your_func gets called then

Cordova viewport problem solved

Include the viewport settings in Cordova If you are facing the auto zooming problem of cordova then go read on the full article. Cordova actually ignores the viewport meta tag which causes the pixel density problem. So we need to tell cordova that viewport tag is equally important as other tags. To do this, we need to add some code to a file which is specify in the article. Corodva messes with pixels If you are using the latest cordova version or creating the cordova app for latest android versions then you may have faced the zoom malfunctioning.I also faced it when creating an app. Many of you may have already searched the web and found the answer of changing the meta tag attributes to get it working. But adding target-densitydpi=medium-dpi does not solve the problem for latest android versions. It may work for gingerbread but not for kitkat and others. So the final solution which i found was one of the stackexchange answer but rarely found. So i am gonna two things here, i