How to handle `nil` value in Golang

Zero Value is a default value which is obtained by declaring a variable without initializing it.

This post raises more questions than answers (for me). While I’m learning more about what Go’s nil is I’ll be making assumptions based on how the languages behaves. I’ll try to collect the answers from the Go’s source code, but in the mean time: just plain assumptions, feel free correct.

Nil is a typed value

Type information is inherent part of a nil value in Go. Lack of type information is a compilation error:
package main func main() { println(nil) } // Errors with: use of untyped nil

Adding a type information satisfies compiler:
package main func main() { println(interface{}(nil)) }

Nils differ if their types differ

As with any other values of different types, typed nils cannot be compared:
package main func main() { println(interface{}(nil) == (*int)(nil)) } // Compilation error

Similarly it’s possible to convert nil to a “common” empty interface type, but because nil value of func() type gets converted to non-nil value of interface{} type - they’re not equal.
package main func main() { println(nil == interface{}((func())(nil))) } // Outputs: false

Nil is a Zero Value for channels, slices, maps, interfaces, function, and pointer types

Zero Value is a default value which is obtained by declaring a variable without initializing it.

Declaring a boolean value initializes it to false, declaring one of “nil-able types” initializes it to Zero Value which is corresponding (typed) nil value.
package main
import "fmt"
func main() {
fmt.Printf("Func type nil:%#v\n",(func())(nil))
fmt.Printf("Map type nil:%#v\n", map[string]string(nil))
fmt.Printf("Slice type nil:%#v\n", []string(nil))
fmt.Printf("Interface{} type nil:%#v\n", nil)
fmt.Printf("Channel type nil:%#v\n", (chan struct{})(nil))
fmt.Printf("Pointer type nil:%#v\n", (*struct{})(nil))
fmt.Printf("Pointer type nil:%#v\n", (*int)(nil))
// Outputs:
// Func type Nil:(func())(nil)
// Map type Nil:map[string]string(nil)
// Slice type Nil:[]string(nil)
// Interface{} type nil:<nil>
// Channel type nil:(chan struct {})(nil)
// Pointer type nil:(*struct {})(nil)
// Pointer type nil:(*int)(nil)

%#v is a handy verb for printing out nil value with its type, useful for debugging nil related confusions

On a mission to build Next-Gen Community Platform for Developers