Skip to content

Instantly share code, notes, and snippets.

@qbig
Last active April 10, 2019 10:15
Show Gist options
  • Select an option

  • Save qbig/47353fdf7bc4cc6253c52a47c8c6d9f7 to your computer and use it in GitHub Desktop.

Select an option

Save qbig/47353fdf7bc4cc6253c52a47c8c6d9f7 to your computer and use it in GitHub Desktop.
Golang nil

ultimate "zero" value

'nil' is surprising NOT a keyword, but a predeclared identifier

nil of different types means completely DIFFERENT thing!!! eg. nil pointer is different from nil interface !!!

things that could be nil.

map, slice, pointer, interface, channel, func "nil is predeclared identifier representing the zero value for a point, channel, func, interface, map or slice"

nil

  • pointer: points to nothing
  • channel: points to nothing
  • func: points to nothing
  • interface: (concrete-type, value) == (nil, nil)
var s fmt.Stringer // Stringer (nil, nil)
fmt.Println(s == nil) //true

var p *Person            // nil of concrete type *Person !!
var b fmt.Stringer = p  // Stringer (*Person, nil)
fmt.Println(s == nil) // FALSE !!!
  • map: similar to slice
  • slice: slice that doesn't have a backing array, still has len and cap values=0

things that could NOT be nil

struct, string, array, numerics, bool

Making nil Useful, we almost could do anything, as long as we don't de-reference nil (*p when p == nil will panic)

var t *foo
foo.Something() // Should not Panic!!!

// Solution:
type person struct{}
func (p *person) sayHi(){fmt.Println("hi")} // works!!!
func (p *person) DoSomething() {
  if p == nil {
    // anything without painc! eg. return
  }
  
  // anything else
}

func (t *tree) Sum() int {
  if t == nil {
    return 0
  }
  
  return t.v + t.l.Sum() + t.r.Sum()
}

func (t *tree) String() string {
  if t == nil {
    return ""
  }
  
  return fmt.Sprint(t.l, t.v, t.r)
}

func (t *tree) Find(v) bool {
  if t == nil {
    return false
  }
  
  return t.v == v || t.l.Find(v) || t.r.Find(v)
}

Useful nil!!!!!!!

  • pointer: many things CALL METHODS!, as long as we don't de-ref *p
  • channel: many things, stop a channel
  • func: default func?
  • interface: different from nil pointer!
  • map: we can do anything READONLY! m[key] works!!
  • slice: anything as a zero values, as long as we don't s[index]

You can appending to a nil slice!!!!, just don't do x[i]!!!

You can iterate over a nil map!!!!, we CAN do x[key]!!! anything readonly is FINE!!!

nil/closed channel is weird!

You can read<-c or writec<-x from nil channel(block forever), just don't close(c)!!!

nil chan is different from closed chan

checking a closed chan by v, ok := <-c, sending to a closed chan will panic!

we could close a channel by setting it as nil c = nil

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment