Magic of Empty Interface in Golang: Different Ways to Use It

Robin
Updated on November 17, 2023

The empty interface (interface{}) in Golang holds a unique position, offering incredible versatility and flexibility. It is a special type that has no methods associated with it.

Therefore, an empty interface serves as a universal type that can hold values of any type. It is often used in situations where you need to work with values of different types without knowing the specific type in advance.

There are many places in your Golang code where you can utilize an empty interface to handle a wide range of data and make it more flexible.

Dynamic Type Variables With Empty Interface in Golang

Golang is a strictly typed language. Whenever you want to declare a variable in Go, you also have to specify a type for it. You can't store different types of data in a single variable.

But imagine you want a variable that could dynamically change its type and adapt to whatever data you throw at it. You can achieve such dynamic type variables using the empty interface.

          package main

import "fmt"

func main() {
    var dynamic interface{} // Declare a variable with an empty interface type

    dynamic = 42 // Assign an int value
    fmt.Println("Dynamic variable value:", dynamic)

    dynamic = "Hello, world!" // Assign a string value
    fmt.Println("Dynamic variable value:", dynamic)

    dynamic = 3.14 // Assign a float value
    fmt.Println("Dynamic variable value:", dynamic)
}

        

In this example, we define a variable called "dynamic" of type interface{}. This allows us to assign values of different types to it.

Initially, we assign an int value to the dynamic variable and print its value. Then, we reassign it with a string and print the updated value. Finally, we assign a float and print the value again.

The beauty of using the empty interface is that the dynamic variable can adapt to any type we assign to it. This flexibility enables us to handle various types of data seamlessly within a single variable.

Also Read: Understanding All Data Types in Golang: A Complete Guide


Use Empty Interface to Pass Any Type of Function Argument

When you create a function with some parameters in Golang, you have to specify the type of those parameters as well. That means, your function can only handle those specific types of data.

Consider a scenario where you want to create a function that accepts any type of value as its argument. It is possible by setting the argument type as interface{} empty interface.

          package main

import "fmt"

func printValue(value interface{}) {
	fmt.Println("Value:", value)
}

func main() {
	printValue(42)             // Pass an int value
	printValue("Hello, Go!")   // Pass a string value
	printValue(3.14)           // Pass a float value
}

        

We have a function called printValue() that takes an argument of type interface{}. The empty interface allows us to pass any type of value to this function.

Inside the printValue() function, we simply print the value passed to it. The magic lies in the fact that we can pass values of different types (int, string, float) without explicitly specifying the type.

Also Read: Type Aliases in Golang: Create Custom Names For Your Types


Pass Any Number of Function Arguments With Empty Interface

In the previous section, you have seen how to pass any type of argument to a function using an empty interface type. You also have the freedom to create functions that accept any number of arguments, regardless of their types.

Suppose you want to create a function where you can pass multiple arguments without any fixed limit and it will print them all.

          package main

import "fmt"

func printValues(args ...interface{}) {
	for _, arg := range args {
		fmt.Println(arg)
	}
}

func main() {
	printValues(42, "Hello, Go!", 3.14, true)
}

        

We have the printValues() function, which takes a different type of argument. The ...interface{} syntax allows us to pass any number of arguments to the function.

Now, you can call this function with any number of arguments and they can be any type. Inside the function, you use a loop to iterate through each argument passed.

Also Read: Functions VS Methods in Golang: Understanding the Differences


Type Assertion for Empty Interface

We use type assertion in Golang to extract the underlying value and determine its actual type when working with the empty interface.

As you know an empty interface can hold any type of data. But while using its value in our program, Golang needs to know the type of data it is working with. That is why you have to use type assertion with an empty interface type.

          package main

import "fmt"

func printValue(value interface{}) {
	intValue, ok := value.(int)

	if ok {
		fmt.Println("It is an int:", intValue)
		return
	}

	strValue, ok := value.(string)

	if ok {
		fmt.Println("It is an string:", strValue)
		return
	}

	fmt.Println("It is not an int or string")
}

func main() {
	printValue(42)
	printValue("Hello, Go!")
	printValue(3.14)
}
        

Output:

          It is an int: 42
It is a string: Hello, Go!
It is not an int or string
        

The printValue() function accepts the value argument of any type. Therefore, if you want to use it in your function to perform any type of operation, you have to confirm its type first.

First, we attempt to assert the value of an int using the value.(int) syntax. It returns two things: the underlying value and a boolean. If the value argument is of type int, the ok variable will be true and intValue variable will contain the actual value.

If it is not an int, the ok variable will be false and intValue variable will contain 0 (it is the default value for an int variable).

You can also use the type assertion technique to check other types of data as well like, string, float, boolean, etc.


Conclusion

The empty interface in Golang offers a remarkable level of flexibility and versatility in handling values of different types. Throughout this blog post, we've explored what it is and its various use cases.

You can use it as a variable type to hold various data without creating multiple variables. An empty interface is helpful to accept any type of function argument as well as any number of arguments in a function.

Just you have to keep in mind that it is required to use type assertion to get the underlying value and the actual type of an empty interface (interface{}) type in Golang before using it in your code.

Related Posts