null - nil detection in Go

ID : 20162

viewed : 18

Tags : gonullgo

Top 5 Answer for null - nil detection in Go

vote vote


The compiler is pointing the error to you, you're comparing a structure instance and nil. They're not of the same type so it considers it as an invalid comparison and yells at you.

What you want to do here is to compare a pointer to your config instance to nil, which is a valid comparison. To do that you can either use the golang new builtin, or initialize a pointer to it:

config := new(Config) // not nil 


config := &Config{                   host: "",                    port: 22,                  } // not nil 


var config *Config // nil 

Then you'll be able to check if

if config == nil {     // then } 
vote vote


In addition to Oleiade, see the spec on zero values:

When memory is allocated to store a value, either through a declaration or a call of make or new, and no explicit initialization is provided, the memory is given a default initialization. Each element of such a value is set to the zero value for its type: false for booleans, 0 for integers, 0.0 for floats, "" for strings, and nil for 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.

As you can see, nil is not the zero value for every type but only for pointers, functions, interfaces, slices, channels and maps. This is the reason why config == nil is an error and &config == nil is not.

To check whether your struct is uninitialized you'd have to check every member for its respective zero value (e.g. host == "", port == 0, etc.) or have a private field which is set by an internal initialization method. Example:

type Config struct {     Host string       Port float64     setup bool }  func NewConfig(host string, port float64) *Config {     return &Config{host, port, true} }  func (c *Config) Initialized() bool { return c != nil && c.setup } 
vote vote


I have created some sample code which creates new variables using a variety of ways that I can think of. It looks like the first 3 ways create values, and the last two create references.

package main  import "fmt"  type Config struct {     host string     port float64 }  func main() {     //value     var c1 Config     c2 := Config{}     c3 := *new(Config)      //reference     c4 := &Config{}     c5 := new(Config)      fmt.Println(&c1 == nil)     fmt.Println(&c2 == nil)     fmt.Println(&c3 == nil)     fmt.Println(c4 == nil)     fmt.Println(c5 == nil)      fmt.Println(c1, c2, c3, c4, c5) } 

which outputs:

false false false false false { 0} { 0} { 0} &{ 0} &{ 0} 
vote vote


You can also check like struct_var == (struct{}). This does not allow you to compare to nil but it does check if it is initialized or not. Be careful while using this method. If your struct can have zero values for all of its fields you won't have great time.

package main  import "fmt"  type A struct {     Name string }  func main() {     a := A{"Hello"}     var b A      if a == (A{}) {         fmt.Println("A is empty") // Does not print     }       if b == (A{}) {         fmt.Println("B is empty") // Prints     }  }

vote vote


In Go 1.13 and later, you can use Value.IsZero method offered in reflect package.

if reflect.ValueOf(v).IsZero() {     // v is zero, do something } 

Apart from basic types, it also works for Array, Chan, Func, Interface, Map, Ptr, Slice, UnsafePointer, and Struct. See this for reference.

Top 3 video Explaining null - nil detection in Go