2

I have the following code to test when golang interface value is false.

package main

import (
    "fmt"
)

func Foo(x interface{}) {
    fmt.Println("33, x == nil = ", x == nil)
}
func main() {
    var x *int = nil
    fmt.Println("11, x == nil = ", x == nil)

    var a interface{}
    fmt.Println(22, &a, &a == nil, a == nil) // 0xc0000935c0 false true
    Foo(x)
}

Result is

11, x == nil =  true
22 0xc00010a040 false true
33, x == nil =  false

I don't understand the output. Especially, I do not understand why &a is not nil because a is not initialized. Is there anyone can help me to explain the result? Thanks.

2

1 Answer 1

10

In go you need to remember two points when it comes to interface nil values:

  1. A nil interface value, which contains no value at all is not the same as an interface value containing a value that happens to be nil.
  2. An interface holding a nil value is not nil

Example explaining 1 & 2:

package main

import "fmt"

func main() {
    var i1 interface{}
    fmt.Println("a == nil: ", i1 == nil)

    var i2 interface{}
    var p *int = nil
    i2 = p
    fmt.Println("b == nil: ", i2 == nil)
}

Output:

a == nil:  true
b == nil:  false

How it works behind the scenes:

Basically an interface in go consists of two things: a dynamic type and a dynamic value. When you assign any value to a nil *int to an interface, now its dynamic type is *int and dynamic value is nil, and therefore the interface now is non-nil and any comparison with nil would result in a false

An interface equals nil only if both its dynamic type and dynamic value are nil.

In your case:

You need to extract the dynamic value of the interface x before you compare it with a nil.

Refer the below code:

package main

import (
    "fmt"
)

func Foo(x interface{}) {
    fmt.Println("22, x == nil = ", (x).(*int) == nil)//22, x == nil =  true
}
func main() {
    var x *int = nil
    fmt.Println("11, x == nil = ", x == nil)// 11, x == nil =  true
    Foo(x)
}

Output:

11, x == nil =  true
22, x == nil =  true
Sign up to request clarification or add additional context in comments.

1 Comment

I like this answer because it is short but clearly shows the ambiguity with a simple example. Why support nil concrete type values at all? The golang authors felt the ambiguity of this case was worth it to permit methods that can be well defined when 'this' or the receiver are nil. For example, Google's protobuf library generates Getters which are well defined when their receiver is nil.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.