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
?
-
2It might be better if Go used explicitly typed nil like Swift `Optional
`. – eonil Jul 26 '15 at 00:56 -
Related, find some reasoning and explanation here: [Hiding nil values, understanding why golang fails here](http://stackoverflow.com/questions/29138591/hiding-nil-values-understanding-why-golang-fails-here) – icza Sep 03 '15 at 05:08
4 Answers
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.

- 1,785
- 10
- 15
-
3Unless the error message you're referring to is "Error communicating with remote server." (which is what I got), you might want to include more information directly in your answer rather than via a link. – Keith Thompson Nov 04 '13 at 04:30
-
1I'd emphasize the point here that calling typed methods on `nil` is both meaningful and useful. – Dustin Nov 05 '13 at 09:26
-
@KeithThompson Good point. I've incorporated the code as well. Dustin, Good point. That's tangential to the question, but worth mentioning in brief. Thanks both of you! – Sean Nov 15 '13 at 23:06
-
For those looking for the syntax: `var SomeNil := SomeType(nil)`. If I later use "SomeNil" to compare to a function (SomeType being a function here), it doesn't work though, claiming "func can only be compared to nil" – Eric Burel Nov 17 '22 at 14:42
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.
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.

- 1
- 1

- 18,604
- 4
- 49
- 61
-
3"is actually the value of uninitialized variables" Technically, it's called the "zero value" for the type. All types have a zero value. Variables are not uninitialized. – newacct Nov 05 '13 at 02:40
-
@newacct I'm using the terminology found in the language spec (http://golang.org/ref/spec) Where they state "The value of an uninitialized slice is `nil`", "The value of an uninitialized pointer is `nil`" etc. From the same document I can see that you're correct that the "zero value" for all of the types I mentioned in my answer is `nil`. I presume a loose, imprecise definition for "zero value" is "uninitialized" as the Go authors seem happy to use both in the actual spec. I've updated my answer, thanks for the correct terminology. – Intermernet Nov 05 '13 at 05:51
All variables in Go 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.

- 2,308
- 1
- 22
- 37

- 11,584
- 3
- 57
- 71
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?

- 51,587
- 17
- 154
- 173