back

Understanding nil

What is nil? When do we need to use nil? 1

What is nil?

In Go, nil is a predefined identifier that represents the zero value of many types and has no type of its own.

A zero value is the default value assigned to a variable of a given type if no value is specified. Some common zero values in Go include 0 for integers, false for booleans, “” for strings, and nil for pointers, slices, maps, channels, interfaces, and functions. Understanding zero values is important when initializing variables to ensure that they are not accidentally left in an uninitialized state.

How to fix a pointer receiver with nil?

panic example
package main

import "fmt"

type Person struct {
  Name string
}

func (p *Person) GetName() string {
  return p.Name
}

func main() {
  var p *Person            // p is pointer, zero value of p is nil
  fmt.Println(p.GetName()) // panic: runtime error: invalid memory address
  // panic: runtime error: invalid memory address or nil pointer dereference
}


how to fix it?
package main

import "fmt"

type Person struct {
  Name string
}

func (p *Person) GetName() string {
  if p == nil {
    return "empty"
  }
  return p.Name
}

func main() {
  var p *Person            // p is pointer, zero value of p is nil
  fmt.Println(p.GetName()) // empty
}


another pattern
package main

import "fmt"

type Node struct {
  next  *Node
  value int
}

func (n *Node) Next() *Node {
  if n == nil {
    return nil
  }

  return n.next
}

func (n *Node) Len() int {
  if n == nil {
    return 0
  }

  cnt := 0

  c := n
  for c != nil {
    c = c.Next()
    cnt++
  }

  return cnt
}

func main() {
  n0 := &Node{value: 2}
  var n1 *Node = &Node{value: 5}
  var n2 *Node
  n0.next = n1
  n1.next = n2

  fmt.Println("root node length:", n0.Len())

  fmt.Println(n2 == nil) // true
  fmt.Println(n2.Len())  // 0
}