How to check if struct is empty in GO? [SOLVED]

How to check if struct is empty in GO? [SOLVED]

This article describes a few methods for determining whether a struct in Go is empty. It includes structs having fields that are comparable and non-comparable. Keep in mind that in Go, an empty structure is one whose fields are all initialized with zero values.


Method 1: Compare to the zero value composite literal

In most circumstances, checking in Go for an empty struct is simple. We can use the operator == to its zero valuecomposite literal. The use of == above applies to structs where all fields are comparable. It is necessary to compare each field to its zero value if the struct contains a non-comparable field (slice, map, or function).

In the if statement, parentheses are required around the composite due to a parsing ambiguity.

package main

import (
    "fmt"
)

type Book struct {
    Name   string
    Author string
}

func main() {
    var book1 Book

    book2 := Book{
        Name:   "John John",
        Author: "Author1",
    }

    fmt.Println("Book1 is empty?: ", book1 == Book{}) // true
    fmt.Println("Book2 is empty?: ", book2 == Book{}) // false
}

Output:

Book1 is empty?:  true
Book2 is empty?:  false

Method 2: Compare the struct pointer to the nil

In the previous chapter, we already know that the zero value of a pointer is nil. So to check if a pointer of a struct is zero or not, we can compare it to nil or to the zero value composite literal. The example below shows how we can do that in Golang:

package main

import "fmt"

type Book struct {
    Name   string
    Author string
}

func main() {
    var book1 *Book
    book2 := &Book{}
    book3 := &Book{Name: "Book1", Author: "author1"}

    // compare to nil
    if book1 == nil {
        fmt.Println("Book1 is empty")
    } else {
        fmt.Println("Book1 is not empty")
    }

    // compare to composite literal
    if *book2 == (Book{}) {
        fmt.Println("Book2 is empty")
    } else {
        fmt.Println("Book2 is not empty")
    }

    if *book3 == (Book{}) {
        fmt.Println("Book3 is empty")
    } else {
        fmt.Println("Book3 is not empty")
    }
}

Output:

Book1 is empty
Book2 is empty
Book3 is not empty

Method 3: Using thereflect.DeepEqual() function

The preceding method will not work if the structure is a slice, map, or function, or if it has a non-comparable field. However, you can use the reflect package with the reflect.DeepEqual() function instead as illustrated below:

package main

import (
    "fmt"
    "reflect"
)

type Book struct {
    Name    string
    Author  string
    Version []string
}

func main() {
    var book1 Book

    book2 := Book{
        Name:    "John John",
        Author:  "Author1",
        Version: []string{"V1.0", "V1.1"},
    }

    // error because can not use == for Version field
    // fmt.Println("Book1 is empty?: ", book1 == Book{})
    // fmt.Println("Book2 is empty?: ", book2 == Book{})
    fmt.Println("Book1 is empty?: ", reflect.DeepEqual(book1, Book{}))
    fmt.Println("Book2 is empty?: ", reflect.DeepEqual(book2, Book{}))
}

Output:

Book1 is empty?:  true
Book2 is empty?:  false

Note that if we use the == operator, the system will prompt the message “invalid operation: book1 == Book{} (struct containing []string cannot be compared”

image


Method 4: Using the isZero() function

With Go 1.13 it is possible to use the newisZero() function:

func (v Value) IsZero() bool: IsZero reports whether v is the zero value for its type. It panics if the argument is invalid.

The example below illustrates how we can use the isZero() function to determine if the struct is empty or not:

package main

import (
    "fmt"
    "reflect"
)

type Book struct {
    Name    string
    Author  string
    Version []string
}

func main() {
    var book1 Book

    book2 := Book{
        Name:    "John John",
        Author:  "Author1",
        Version: []string{"V1.0", "V1.1"},
    }

    fmt.Println("Book1 is empty?: ", reflect.ValueOf(book1).IsZero())
    fmt.Println("Book2 is empty?: ", reflect.ValueOf(book2).IsZero())
}

Output:

Book1 is empty?:  true
Book2 is empty?:  false

Method 5: Add an additional field to the struct

We can define our check if the struct has been populated or it is empty. For example, we can add the field “Id” to our Book struct, if this field is 0 or empty, we consider that struct is empty.

package main

import (
    "fmt"
)

type Book struct {
    Name    string
    Author  string
    Version []string
    Id      int
}

func main() {
    var book1 Book

    book2 := Book{
        Name:    "John John",
        Author:  "Author1",
        Version: []string{"V1.0", "V1.1"},
    }

    book3 := Book{
        Name:    "Anna",
        Author:  "Anna",
        Version: []string{"V1.0", "V1.1"},
        Id:      1,
    }

    fmt.Println("Book1 is empty?: ", book1.Id != 0)
    fmt.Println("Book2 is empty?: ", book2.Id != 0)
    fmt.Println("Book3 is empty?: ", book3.Id != 0)
}

Output:

Book1 is empty?:  false
Book2 is empty?:  false
Book3 is empty?:  true

Summary

In this tutorial we have explored different methods to check if struct is empty in golang. I hope this post has given you some insight into Go’s empty struct detection. Please share any additional tips or strategies you may have in the following comments section.


References

https://go.dev/ref/spec#Composite_literals
https://pkg.go.dev/reflect
How to check for an empty struct? - Stack Overflow

Tuan Nguyen

Tuan Nguyen

Data Scientist

Proficient in Golang, Python, Java, MongoDB, Selenium, Spring Boot, Kubernetes, Scrapy, API development, Docker, Data Scraping, PrimeFaces, Linux, Data Structures, and Data Mining. With expertise spanning these technologies, he develops robust solutions and implements efficient data processing and management strategies across various projects and platforms.