What is the empty interface (interface{} / any) in Go and when is it used?
Learn what Go's empty interface (interface{} / any) is, why every type satisfies it, and how to safely recover values with type assertions and type switches.
Expected Interview Answer
The empty interface, written interface{} (aliased as any since Go 1.18), is an interface with zero methods, so every type satisfies it — a variable of that type can hold a value of any concrete type.
Because it carries no method requirements, it is Go's way to write code that accepts values of unknown or heterogeneous type, such as fmt.Println's arguments, JSON decoding into map[string]any, or generic container helpers before generics existed. To use the underlying value you must recover its real type with a type assertion (v.(T)) or a type switch, since the empty interface exposes no behaviour on its own. Overusing it sacrifices compile-time type safety, so idiomatic Go now prefers named interfaces or generics where possible.
- Accepts values of any concrete type
- Enables heterogeneous containers and generic-ish APIs
- Powers reflection-based libraries like encoding/json and fmt
- The `any` alias reads more clearly than interface{}
- Bridges code where the type is genuinely unknown at compile time
AI Mentor Explanation
Think of a 12th-man slot on a cricket squad that any player can fill regardless of specialism — batter, bowler, or keeper. The slot itself demands no particular skill, so anyone qualifies. But before that person actually plays, the captain must check what they really are and assign a role. The empty interface is that slot: it holds any value, but you type-assert to learn the real player and what they can do.
Step-by-Step Explanation
Step 1
Declare the holder
Write a variable or parameter as interface{} or any so it can accept a value of any type.
Step 2
Assign any value
Store an int, string, struct, or slice into it; the compiler accepts all of them because the interface has no method set.
Step 3
Recover the concrete type
Use a type assertion v, ok := x.(string) to safely extract the real value, checking ok to avoid a panic.
Step 4
Branch with a type switch
When multiple types are possible, use switch t := x.(type) to handle each concrete type in its own case.
Step 5
Prefer alternatives when you can
Replace empty interfaces with named interfaces or generics where the accepted types are actually constrained.
What Interviewer Expects
- That interface{} has zero methods so every type satisfies it
- Knowledge that `any` is a Go 1.18 alias for interface{}
- Understanding that type assertions or type switches recover the concrete type
- Awareness of the comma-ok form to avoid panics
- Recognition that generics now replace many empty-interface uses
Common Mistakes
- Doing an unchecked assertion x.(T) that panics on the wrong type
- Believing interface{} makes code faster — it adds boxing and reflection cost
- Using it everywhere and losing compile-time type safety
- Confusing `any` with a distinct type rather than an alias for interface{}
- Forgetting that a nil interface{} is not equal to a typed nil pointer stored in it
Best Answer (HR Friendly)
“The empty interface in Go is a flexible container that can hold a value of absolutely any type, which is handy when you don't know the type in advance. The trade-off is that you have to check what's really inside before you use it, and modern Go often prefers safer options like generics.”
Code Example
func describe(x any) string {
switch v := x.(type) {
case int:
return fmt.Sprintf("int: %d", v)
case string:
return fmt.Sprintf("string: %q", v)
default:
return fmt.Sprintf("unknown type: %T", v)
}
}
func main() {
var box any = 42
if n, ok := box.(int); ok {
fmt.Println("got int", n)
}
fmt.Println(describe("hi"))
}Follow-up Questions
- What is the difference between a type assertion and a type switch?
- How do generics reduce the need for interface{}?
- Why can a non-nil interface{} holding a nil pointer still be != nil?
- What performance costs does boxing into an empty interface introduce?
- How does encoding/json use interface{} when decoding unknown JSON?
MCQ Practice
1. How many methods does the empty interface require a type to implement?
The empty interface has an empty method set, so every type satisfies it automatically.
2. What is `any` in modern Go?
Since Go 1.18, `any` is a predeclared alias for interface{}; they are interchangeable.
3. Which is the safe way to extract a string from an any value?
The comma-ok form s, ok := x.(string) returns false instead of panicking when the type doesn't match.
Flash Cards
What is interface{}? — An interface with zero methods, satisfied by every type, so it can hold any value.
What is `any`? — A Go 1.18+ alias for interface{} that reads more clearly.
How do you get the concrete value back? — Use a type assertion x.(T) or a type switch switch x.(type).
Safe assertion form? — v, ok := x.(T) — ok is false instead of panicking on a mismatch.
Modern alternative to interface{}? — Generics (type parameters) when the accepted types are actually constrained.
Continue Learning
Related Interview Questions
What is a struct in Go and how does struct embedding provide composition?
medium
What is the difference between a value receiver and a pointer receiver in Go?
medium
What are Go generics and how do type parameters and constraints work?
medium
What are Go interfaces and how does implicit implementation work?
medium