Reputation: 9185
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
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