Menu
Coddy logo textTech

Empty Interface (any)

Part of the Object Oriented Programming section of Coddy's GO journey — lesson 28 of 107.

The empty interface is an interface with zero methods. Since every type in Go has at least zero methods, every type automatically satisfies the empty interface. This makes it capable of holding values of any type.

var anything interface{}

anything = 42
anything = "hello"
anything = true
anything = []int{1, 2, 3}

Starting with Go 1.18, the keyword any was introduced as an alias for interface{}. They're completely interchangeable, but any is cleaner to read.

var value any = "Go is awesome"

The empty interface is useful when you need to handle values of unknown or varying types. Functions like fmt.Println use it to accept arguments of any type:

func PrintAnything(v any) {
    fmt.Println("Value:", v)
}

func main() {
    PrintAnything(100)
    PrintAnything("text")
    PrintAnything(3.14)
}

However, there's a tradeoff. When a value is stored in an empty interface, you lose access to its specific type information.

You can't directly call methods or access fields without first extracting the underlying type. The next lessons will cover how to retrieve the concrete type from an empty interface using type assertions and type switches.

challenge icon

Challenge

Easy

Let's build a flexible storage container that can hold values of any type using the empty interface. You'll create a simple box that demonstrates how any allows you to store different types in the same structure.

You'll organize your code across two files:

  • box.go: Define a Box struct with a single field Content of type any. Create a NewBox constructor function that accepts a value of any type and returns a pointer to a Box containing that value. Add a Describe method that returns a string showing what's stored in the box.
  • main.go: Read different values from input, create boxes containing an integer, a string, and a boolean, then print the description of each box to show how the same Box type can hold completely different values.

The following inputs will be provided:

  • Line 1: An integer value
  • Line 2: A string value
  • Line 3: A boolean value (true or false)

Your Describe method should return a string in this format:

Box contains: [value]

For example, given 42, hello, and true, your output should be:

Box contains: 42
Box contains: hello
Box contains: true

The key insight here is that your single Box struct can store an integer, a string, or a boolean—all because the any type accepts values of any type. Each box holds something different, yet they're all the same Box type.

Cheat sheet

The empty interface (interface{}) is an interface with zero methods. Since every type in Go has at least zero methods, every type automatically satisfies the empty interface, making it capable of holding values of any type.

var anything interface{}

anything = 42
anything = "hello"
anything = true
anything = []int{1, 2, 3}

Starting with Go 1.18, the keyword any was introduced as an alias for interface{}. They're completely interchangeable, but any is cleaner to read:

var value any = "Go is awesome"

The empty interface is useful for handling values of unknown or varying types. Functions can accept arguments of any type:

func PrintAnything(v any) {
    fmt.Println("Value:", v)
}

func main() {
    PrintAnything(100)
    PrintAnything("text")
    PrintAnything(3.14)
}

Tradeoff: When a value is stored in an empty interface, you lose access to its specific type information. You can't directly call methods or access fields without first extracting the underlying type using type assertions or type switches.

Try it yourself

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

func main() {
	reader := bufio.NewReader(os.Stdin)

	// Read integer value
	line1, _ := reader.ReadString('\n')
	intVal, _ := strconv.Atoi(strings.TrimSpace(line1))

	// Read string value
	line2, _ := reader.ReadString('\n')
	strVal := strings.TrimSpace(line2)

	// Read boolean value
	line3, _ := reader.ReadString('\n')
	boolVal, _ := strconv.ParseBool(strings.TrimSpace(line3))

	// TODO: Create boxes for each value using NewBox
	// TODO: Print the description of each box using the Describe method

	// Use the variables to avoid compilation errors (remove these lines when implementing)
	_ = intVal
	_ = strVal
	_ = boolVal

	// Example output format:
	// fmt.Println(box.Describe())
}
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Object Oriented Programming