In the previous post, I already talked about the zero values and nil in
Golang. In today’s article, we will discuss how to detect nil value in
Go.**nil**is a predefined identifier in Go that represents zero
values of many types.nil is usually mistaken as null (or NULL) in
other languages, but they are different.
Using nil in Golang
We can usenil without declaring it. nil can represent
the zero values of many data types:
- pointer types (including type-unsafe ones).
- map types.
- slice types.
- function types.
- channel types.
- interface types.
Common nil detection in Golang
When storage is allocated for
avariable, either through a declaration or a call
ofnew, or when a new value is created, either through a composite
literal or a call ofmake, and no explicit initialization is provided,
the variable or value is given a default value. Each element of such a
variable or value is set to thezero valuefor its type:falsefor
booleans,0for numeric types,""for strings, andnilfor
pointers, functions, interfaces, slices, channels, and maps. This
initialization is done recursively, so for instance each element of an
array of structs will have its fields zeroed if no value is specified.
In the example below, we will try to convert a string to
unit8 and see how
we can catch the error if it is not nil:
package main
import (
"fmt"
"strconv"
)
func main() {
s := "111a"
fmt.Printf("%v %T\n", s, s)
in, err := strconv.Atoi(s)
// catch the error if it is not nil
if err != nil {
fmt.Println(err) //strconv.Atoi: parsing "111a": invalid syntax
}
fmt.Printf("%v %T\n", in, in) // 0 int
s2 := "111"
fmt.Printf("%v %T\n", s2, s2)
in2, err := strconv.Atoi(s2)
if err != nil {
fmt.Println(err)
}
fmt.Printf("%v %T\n", in2, in2) // 0 int
}
Output:
111a string
strconv.Atoi: parsing "111a": invalid syntax
0 int
111 string
111 int
Explanation
In the code shown below, we try to
handle errors by creating an error variable which is
an error type. The zero value for the error type is nil, so we can
use the operator != to compare our variable to nil. If it is not
nil, it means our program has some problems, we will print the
error message and try to handle this case.

Check if a pointer is nil or not
In this example, the pointer is checked whether it is a nil pointer or not:
package main
import "fmt"
type Test struct {
}
func main() {
var ptr *Test // pointer
var intVal = 123
var ptr1 *int = &intVal
fmt.Printf("ptr is a nil pointer?: %v\n", ptr == nil)
fmt.Printf("ptr1 is a nil pointer?: %v\n", ptr1 == nil)
}
Output:
ptr is a nil pointer?: true
ptr1 is a nil pointer?: false
Check if a struct is nil or not
In this example, we will try to compare a struct instance to nil.
package main
import "fmt"
type Config struct {
Host string
Port float64
Username string
Password string
Setup bool
}
func main() {
var conf Config
if conf == nil {
fmt.Println("The config is nil!")
} else {
fmt.Println("The config is not nil")
}
}
Explanation
You are comparing a structure instance and nil, which is why the
compiler prompts an error message. Since they are not the same type, so
the comparison is invalid. The elements of an array or struct will have
their fields zeroed if no value is specified. So there’s no way to set a
struct value to nil. But you could set the value of a pointer to a
struct to nil. As mentioned above, the zero value of pointer types is
nil.
package main
import "fmt"
type Config struct {
Host string
Port float64
Username string
Password string
Setup bool
}
func main() {
var conf *Config // nil
// not nil
conf2 := &Config{
Host: "www.golinuxcloud.com",
Port: 22,
Username: "testuser",
Password: "pwd",
}
if conf == nil {
fmt.Println("The config is nil!")
} else {
fmt.Println("The config is not nil")
}
if conf2 == nil {
fmt.Println("The config is nil!")
} else {
fmt.Println("The config is not nil")
}
}
Output:
The config is nil!
The config is not nil
Check if an interface is nil or not
In this example, the interface is checked whether it is a nil interface or not.
package main
import (
"fmt"
)
type TestInterface interface {
Summary() string
}
type MyString struct {
Message string
}
// Implementing methods of
func (myStr MyString) Summary() string {
return "This is a test message" + myStr.Message
}
func main() {
var interf TestInterface
fmt.Printf("interf is a nil interface: %v\n", interf == nil)
var interf2 TestInterface
interf2 = MyString{"from GoLinuxCloud"}
fmt.Printf("interf2 is a nil interface: %v\n", interf2 == nil)
}
Output:
interf is a nil interface: true
interf2 is a nil interface: false
Check if a slice is nil or not
In this example, we are going to check if a slice is nil or not. For
the slice, you must clearly understand about an empty and a nil slice.
nil and empty slices (with 0 capacity) are not the same, but their
observable behavior is the same (almost all the time):
- We can call the builtin
len()andcap()functions for both nil and empty slice - We can iterate through them with
for range(will be 0 iterations)
package main
import "fmt"
func main() {
var slice1 []int // nil slice
slice2 := []int{} // non-nil, empty slice
slice3 := make([]int, 0) // non-nil, empty slice
fmt.Println("slice1", len(slice1), slice1 == nil, slice1[:], slice1[:] == nil)
fmt.Println("slices2", len(slice2), slice2 == nil, slice2[:], slice2[:] == nil)
fmt.Println("slice3", len(slice3), slice3 == nil, slice3[:], slice3[:] == nil)
}
Output:
slice1 0 true [] true
slice2 0 false [] false
slice3 0 false [] false
Check if a map is nil or not
The following example shows how to check if a map is empty using the length check and check if the map is nil or not:
package main
import "fmt"
func main() {
tempMap := make(map[string]string) // empty map
var tempMap2 map[string]string // nil map
if len(tempMap) == 0 {
fmt.Println("tempMap is empty")
} else {
fmt.Println("tempMap is not empty")
}
if tempMap2 == nil {
fmt.Println("tempMap2 is nil")
} else {
fmt.Println("tempMap2 is not nil")
}
}
Output:
tempMap is empty
tempMap2 is nil
Summary
As you can see,nil is not the zero value for every type but only for
pointers, functions, interfaces, slices, channels, and maps. For nil
detection, we simply use the comparator !=. Besides that, some
packages provide the IsZero() function to check if it is nil or not.
For example, the time.Time type has the IsZero() which reports
whether the variable represents the zero
time
instant, January 1, year 1, 00:00:00 UTC.
References
https://go.dev/ref/spec#The_zero_value
https://go.dev/doc/tutorial/handle-errors
https://pkg.go.dev/errors

![GO nil detection [interface, slice, pointer, struct, map]](/golang-nil-detection/golang-nil-detection.jpg)
