Nil in go

I see a lot of code in Go for nil detection, for example:

if err != nil { // handle the error } 

however, I have a structure like this:

 type Config struct { host string port float64 } 

and config is an instance of Config when I do this:

 if config == nil { } 

there is a compilation error saying: cannot convert nil to type Config

+83
null go
Nov 27 '13 at 10:41
source share
5 answers

The compiler indicates an error for you, you are comparing an instance of the structure and zero. They are not of the same type, so he considers this an unacceptable comparison and yells at you.

What you want to do is compare the pointer to your config instance with nil, which is a valid comparison. To do this, you can use the new built-in golang or initialize a pointer to it:

 config := new(Config) // not nil 

or

 config := &Config{host: myhost.com, port: 22} // not nil 

or

 var config *Config // nil 

Then you can check

 if config == nil { // then } 
+109
Nov 27 '13 at 10:47
source share

In addition to Oleiade, see spec for null values :

When memory is allocated to store a value, either through an declaration, or by a make call, or by a new one, and explicit initialization is not provided, the default initialization is assigned to the memory. Each element of this value is set to zero for its type: false for booleans, 0 for integers, 0.0 for float, "" for lines and nil for pointers, functions, interfaces, slices, channels and maps. This initialization is performed recursively, therefore, for example, each element of the array of structures will have its own fields if they are not specified.

As you can see, nil is not a null value for each type, but only for pointers, functions, interfaces, fragments, channels and maps. This is why config == nil is an error and &config == nil not.

To check if your structure is structured, you will need to check each participant for its corresponding zero value (for example, host == "" , port == 0 , etc.) or have a private field that is set using the 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 } 
+45
Nov 27 '13 at 14:24
source share

I created some sample code that creates a new variable using various ways that I can think of. It seems that the first 3 methods create values, and the last two create links.

 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} 
+12
May 28 '14 at 17:53
source share

You can also check like struct_var == (struct{}) . This does not allow comparison with nil, but checks to see if it is initialized or not. Be careful when using this method. If your structure can have null values for all of its fields, you won’t have a 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 } } 

http://play.golang.org/p/RXcE06chxE

+5
Aug 22 '15 at 2:02
source share

The language specification describes the behavior of comparison operators:

comparison operators

In any comparison, the first operand must be assigned to the type of the second operand, or vice versa.




Assignability

The value x is assigned to a variable of type T ("x is assigned to T") in any of these cases:

  • x type is identical to T.
  • x types V and T have the same base types, and at least one of V or T is not a named type.
  • T is the type of interface, and x implements T.
  • x is the bidirectional value of a channel, T is a channel type, x types V and T have the same element types, and at least one of V or T is not a named type.
  • x is the predefined identifier nil, and T is the type of pointer, function, slice, map, channel, or interface.
  • x is an untyped constant represented by a value of type T.
+2
Nov 12 '15 at 8:07
source share



All Articles