Here are four ways to check for an empty struct in Go:
- Comparing with a zero-value composite literal
- Using the reflect.DeepEqual() function
- Comparing the struct pointer to the nil
- Using the isZero() function
Method 1: Comparing with a zero-value composite literal
package main
import "fmt"
type Student struct {
Name string
Age int
}
func main() {
var s1 Student
s2 := Student{}
s3 := Student{Name: "Krunal", Age: 30}
fmt.Println(isZero(s1))
fmt.Println(isZero(s2))
fmt.Println(isZero(s3))
}
func isZero(s Student) bool {
return s == Student{}
}
Output
true
true
false
If the struct contains fields that are slices, maps, or pointers, the zero value for these fields will be nil. But a nil slice and an empty (but initialized) slice are different. Similarly, a nil map and an empty (but initialized) map differ.
If you need to check for truly empty values in such cases, you will need to add additional logic.
Comparing large structs in this way might not be very efficient.
If performance is a concern, you might want to maintain a bool flag or use other techniques to track the “emptiness” of the struct.
Method 2: Using the reflect.DeepEqual() function
The built-in comparison using == doesn’t work for structs containing non-comparable fields like slices, maps, or functions. In such cases, it will give a compilation error.
Instead, you can use the DeepEqual() function from the reflect package to compare such structs. This function will recursively compare the contents of the struct, including non-comparable fields.
package main
import (
"fmt"
"reflect"
)
type Data struct {
Numbers []int
Lookup map[string]int
}
func main() {
var d1 Data
d2 := Data{}
d3 := Data{Numbers: []int{1, 2, 3}, Lookup: map[string]int{"one": 1}}
fmt.Println(isZero(d1))
fmt.Println(isZero(d2))
fmt.Println(isZero(d3))
}
func isZero(d Data) bool {
return reflect.DeepEqual(d, Data{})
}
Output
true
true
false
Method 3: Comparing the struct pointer to the nil
To check if a struct’s pointer is zero, we can compare it to nil or the zero-value composite literal.
When you have a pointer to a struct, there are two aspects of “zero-ness” to consider:
- Pointer itself being nil: This means the pointer doesn’t point to any memory address.
- The value the pointer points to is the zero value for the struct type: This means that while the information is not nil, the struct it points to holds the zero values for all its fields.
package main
import (
"fmt"
"reflect"
)
type Person struct {
Name string
Age int
}
func main() {
var p1 *Person // nil pointer
p2 := &Person{} // pointer to zero value of Person
p3 := &Person{"Alice", 25}
fmt.Println(isNilOrZero(p1))
fmt.Println(isNilOrZero(p2))
fmt.Println(isNilOrZero(p3))
}
func isNilOrZero(p *Person) bool {
if p == nil {
return true
}
return reflect.DeepEqual(*p, Person{})
}
Output
true
true
false
Method 4: Using the isZero() function
The isZero() function can be reused to check if a struct (or its pointer) is “empty” or has zero value for its type.
Here’s how you can adapt the function to work for both direct structs and pointers to structs:
package main
import (
"fmt"
"reflect"
)
type Person struct {
Name string
Age int
}
func main() {
var p1 Person
p2 := Person{}
p3 := Person{Name: "Alice", Age: 25}
var pp1 *Person // nil pointer
pp2 := &Person{} // pointer to zero value of Person
pp3 := &Person{"Bob", 30}
fmt.Println(isZero(p1))
fmt.Println(isZero(p2))
fmt.Println(isZero(p3))
fmt.Println(isZero(pp1))
fmt.Println(isZero(pp2))
fmt.Println(isZero(pp3))
}
func isZero(i interface{}) bool {
v := reflect.ValueOf(i)
// If it's a pointer, dereference it
if v.Kind() == reflect.Ptr {
// Check if the pointer itself is nil
if v.IsNil() {
return true
}
v = v.Elem()
}
zeroValue := reflect.Zero(v.Type())
return v.Interface() == zeroValue.Interface()
}
Output
true
true
false
true
true
false
That’s it!

Krunal Lathiya is a seasoned Computer Science expert with over eight years in the tech industry. He boasts deep knowledge in Data Science and Machine Learning. Versed in Python, JavaScript, PHP, R, and Golang. Skilled in frameworks like Angular and React and platforms such as Node.js. His expertise spans both front-end and back-end development. His proficiency in the Python language stands as a testament to his versatility and commitment to the craft.