Have to know the Golang knowledge point nil

Source: Internet
Author: User
Tags builtin comparable
This is a creation in Article, where the information may have evolved or changed.

In Golang nil , many people mistakenly think of NULL in programming languages such as Java, PHP, and so on. But actually Golang's niu is much more complicated, and if not, let's continue reading.

nilFor pre-declared identifiers, defined in builtin/builtin.go ,

// nil is a predeclared identifier representing the zero value for a// pointer, channel, func, interface, map, or slice type.// Type must be a pointer, channel, func, interface, map, or slice typevar nil Type // Type is here for the purposes of documentation only. It is a stand-in// for any Go type, but represents the same type for any given function// invocation.type Type int

Nil value of 0

According to the Go Language specification, any type has a value of 0 when uninitialized: The Boolean type is False, the integer is 0, the string is "", and the 0 values for pointers, functions, interface, slice, channel, and map are nil.

PS: This does not say that the struct struct's 0 value is nil, because the struct's 0 value is related to its properties

nilThere is no default type, although it is a 0 value of more than one type, you must explicitly or implicitly specify the explicit type of each nil usage.

package mainfunc main() {    // 明确.    _ = (*struct{})(nil)    _ = []int(nil)    _ = map[int]bool(nil)    _ = chan string(nil)    _ = (func())(nil)    _ = interface{}(nil)    // 隐式.    var _ *struct{} = nil    var _ []int = nil    var _ map[int]bool = nil    var _ chan string = nil    var _ func() = nil    var _ interface{} = nil}

If you focus on the Golang keyword students will find that there is no nil , that nil is not the keyword, then you can define in the code nil , then nil it will be hidden.

package mainimport "fmt"func main() {    nil := 123    fmt.Println(nil) // 123    var _ map[string]int = nil //cannot use nil (type int) as type map[string]int in assignment}

The address and value size of the nil type

nilThe memory layout of all values of a type is always the same, in other words: Different types nil of memory addresses are the same.

package mainimport (    "fmt")func main() {    var m map[int]string    var ptr *int    var sl []int    fmt.Printf("%p\n", m)       //0x0    fmt.Printf("%p\n", ptr )    //0x0    fmt.Printf("%p\n", sl )     //0x0}

Values are generally nil represented as exceptions in the business. The size of the nil value is always the same as the size of the value with nil the same type as the value non-nil . Therefore, a nil identifier that represents a different 0 value may have a different size.

package mainimport (    "fmt"    "unsafe")func main() {    var p *struct{} = nil    fmt.Println( unsafe.Sizeof( p ) ) // 8    var s []int = nil    fmt.Println( unsafe.Sizeof( s ) ) // 24    var m map[int]bool = nil    fmt.Println( unsafe.Sizeof( m ) ) // 8    var c chan string = nil    fmt.Println( unsafe.Sizeof( c ) ) // 8    var f func() = nil    fmt.Println( unsafe.Sizeof( f ) ) // 8    var i interface{} = nil    fmt.Println( unsafe.Sizeof( i ) ) // 16}

The size is dependent on the compiler and architecture. The above print results are 64-bit architecture and the official Go compiler. For a 32-bit architecture, the size of the print will be half.

For the official Go compiler, the same kind of different types of two nil values are always the same size. For example, the two nil values for two different tile types ([]int and []string] are always the same.

Nil value Comparison

1. Different types nil are not comparable.

package mainimport (    "fmt")func main() {    var m map[int]string    var ptr *int    fmt.Printf(m == ptr) //invalid operation: m == ptr (mismatched types map[int]string and *int)}

In Go, two values of two different comparable types can be compared only if one value can be implicitly converted to another type. Specifically, there are two cases with two different values that can be compared:

    • A type of one of two values is the underlying type of another.
    • A type of one of two values implements the type of another value (must be an interface type).

nilThe value comparison does not deviate from the above rule.

package mainimport (    "fmt")func main() {    type IntPtr *int    fmt.Println(IntPtr(nil) == (*int)(nil))            //true    fmt.Println((interface{})(nil) == (*int)(nil))    //false}

2. Two values of the same type nil may not be comparable
Because map, slice, and function types are not comparable types in Golang, they have a name that is not 不可比拟的类型 , so it nil is also illegal to compare them.

package mainimport (    "fmt")func main() {    var v1 []int = nil    var v2 []int = nil    fmt.Println(v1 == v2)    fmt.Println((map[string]int)(nil) == (map[string]int)(nil))    fmt.Println((func())(nil) == (func())(nil))}

不可比拟的类型The value of the missing is comparable to "pure nil".

package mainimport (    "fmt")func main() {    fmt.Println((map[string]int)(nil) == nil)  //true    fmt.Println((func())(nil) == nil)           //true}

3. Two nil values may not be equal

If one of the two compared nil values is an interface value, and the other is not, assuming that they are comparable, the comparison result is always false. The reason is that the interface value is converted to the type of the interface value before the comparison is made. The converted interface value has a specific dynamic type, but the other interface values are not. That's why the comparison is always wrong.

package mainimport (    "fmt")func main() {    fmt.Println( (interface{})(nil) == (*int)(nil) ) // false}

Problems

1. function return

func nilReturn() (string,error)  {    return nil,nil  //cannot use nil as type string in return argument}

errorthe error type does not have an error because it is an interface type.

Nil Key of 2.map
The key for map is pointer, function, interface, slice, channel, and map, then key can be nil.

package mainimport (    "fmt")func main() {    mmap := make(map[*string]int,4)    a:="a"    mmap[&a] = 1    mmap[nil] = 99    fmt.Println(mmap)   //map[0xc042008220:1 <nil>:99]}

Summarize

Nil is more difficult to understand because we often confuse the nil value and nil type, I hope you students savor the difference.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.