Why does Go have typed nil?

时间秒杀一切 提交于 2020-01-01 03:52:34

问题


Why does Go have typed nil? It throws an explicit interface conformation check for convenience. What's the problem of untyped nil and what did the designers want to solve with typed nil?


回答1:


It sounds like you're asking about this error message:

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

package main

import "fmt"

type A struct {}
type B struct {}

func (a *A) Foo() {
    fmt.Println("A")
}

func (b *B) Foo() {
    fmt.Println("B")
}

func main() {
    n := nil
    n.Foo()
}

This prints:

prog.go:17: use of untyped nil
 [process exited with non-zero status]

In that example, should the program print "A" or "B"?

You have to help the compiler decide. The way you do that is by specifying the type of n.

For example:

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

func main() {
    var n *A
    n.Foo()
}

prints "A".

In other languages, n.Foo() might crash immediately if n is nil or its equivalent. Go's language designers decided to let you determine what should happen instead. If you access the pointer without checking for nil, you get the same behavior as in other languages.




回答2:


This is due to type safety. nil is actually the value of uninitialized variables in Go. The nil values for slices, maps, functions, channels, pointers and interfaces are not the same type, and not comparable. See The language spec for more details.

EDIT: As pointed out by @newacct the correct technical term for this is the "zero value" for the type:

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.

Playground example

There is also some information regarding nil interfaces and errors at Why is my nil error value not equal to nil? in the Go FAQ.




回答3:


All variables in Golang need to have a type. Using := operator infers the type from type of right-side expression.

x := [0]int{}       // var x [0]int
y := make(chan int) // var y chan int
z := map[int]int{}  // var z map[int]int
a := func(int) {}   // var a func(int)
b := 42             // var b int
c := 42.0           // var c float64

For pretty much any expression, its type is unambigous, due to needing to explicitly specify the type somewhere - or in case of number literals, having a default when unspecified. The only exception to this rule is nil.

n := nil // var n ???

nil is a valid value for the following.

  • Pointers
  • Unsafe pointers
  • Interfaces
  • Channels
  • Maps
  • Slices
  • Functions

There isn't a good default for a type when an user types nil, so instead Golang rejects this requiring an explicit type specification.




回答4:


Without typed-nil, you couldn't use the short assignment statement := with the nil value.

a := nil // Error: use of untyped nil
b := error(nil) // OK

It, likewise, enables the following one-liner:

result, err := "A good result", error(nil)

Writing something like the above may provide some convenience on occasion.


Note, however, that nil is not a keyword or a literal -- and Go does not have a built-in or standard typed-nil value. Typed-nil exists only as the result of one of the following:

  • declaring a nillable typed variable with default ("zero value") initialization
  • assigning nil (directly or indirectly) to a typed value
  • casting the nil identifier to a type (as shown in the examples above).

Here's a clip about subtleties with typed nils and interfaces: GopherCon 2015: Kevin Cantwell - What Could Go Wrong?



来源:https://stackoverflow.com/questions/19761393/why-does-go-have-typed-nil

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!