Nil in Golang

isha girdhar
3 min readMar 18, 2019

--

Are nil and null the same thing?

Coming from Java or other programming language background you might think they are but they partly are the same yet somewhat different.

nil is a predeclared identifier in Go that represents zero values for pointers, interfaces, channels, maps, slices and function types. nil being the zero value of pointers and interfaces, uninitialized pointers and interfaces will be nil.So does that mean a string can’t be nil, yes you are right, a string doesn’t qualify to be either of the above-mentioned types and hence can’t be assigned nil.

So what if I do a shorthand declaration with nil

a := nil

This will be a compile-time error use of untyped nilsince nil is untyped and the only untyped value that doesn’t have default type and the compiler has no idea which type it has to assign to a.

Okay now Let’s try to assign a value to a qualified type( a pointer)

var *a int = nil

Yes, this works as expected.

What if I try to return nil from a function

The above program will panic with this error though it will not be a compile-time error since we are returning a nil pointer which is a qualified type for nil

But when we try to reference the ‘str’ attribute of the struct, it will crash.

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x8 pc=0x1092534]

Can we compare two nil values of the same type?

Depends. Let us look at these two code snippets

var m []int = nilvar n []int = nilif m == n {   fmt.Println("equal")}

This will result in compile time error

invalid operation: m == n (slice can only be compared to nil)

Let's look at this one

var i someIntf = nilvar j someIntf = nilif i == j{fmt.Println("equal")}

This works and prints “equal”

Why did it happen?

Because In Go, map, slice and function types don’t support comparison. Comparing two nil values of incomparable types is not allowed.

But uncomparable types can be compared with the bare nil identifier

var m []int = nilvar n []int = nilif m == nil &&  n == nil {   fmt.Println("both are nil")}

error and nil

error is an interface and hence qualify to assigned as nilif err!=nil{
fmt.Println("error encountered"
}

Ranging over Nil channels

Ranging over a nil channel will block the current goroutine forever

for range chan bool(nil) { // block here
fmt.Println("nil ")
}

Ranging over nil slices and maps.

for range []int(nil) {
fmt.Println("nil slice")
}

for range map[string]string(nil) {
fmt.Println("nil map")
}

The number of loop iterations by nil maps and slices is zero. Hence this code snippet won’t print anything.

I hope that helps to understand a little bit about nil !!!

--

--