ThePiachu
ThePiachu

Reputation: 9185

Null vs nil in golang?

I ran into a strange bug today. I had a function:

func Foo(s *someStruct) {
    fmt.Printf("s is %v\n", s)
    if s!=nil {
        fmt.Printf("s is not nil")
        ...
    }
}

I would call the function like:

var s *someStruct
Foo(s)

And then I decided to convert the structure into interface:

func Foo(s someStructInterface) {
    fmt.Printf("s is %v\n", s)
    if s!=nil {
        fmt.Printf("s is not nil")
        ...
    }
}

Which gave me a strange output:

s is null
s is not nil

While I expected to get s is nil, which is what I was getting usually. What is the difference between null and nil in this scenario in Go and how can I check if something is null or nil to execute the code properly?

Upvotes: 4

Views: 12518

Answers (1)

Thundercat
Thundercat

Reputation: 120969

An interface value contains a reference to a type and a value. In the following code:

var s *someStruct
Foo(s)

the interface value passed to Foo contains a reference to the type *someStruct and a nil.

The statement fmt.Printf("s is %v\n", s) outputs s is <nil> because of the following: The %v format prints a value using the default format for the type. The value s contains a pointer type. The default format for a pointer type is %p. The %p format prints nil pointers as <nil>.

The expression s != nil evaluates to true because an interface value is equal to nil if and only if the type reference is nil. In this case, the interface value references the type *someStruct.

Upvotes: 4

Related Questions