I am having the case in which a function with the following code:
func halfMatch(text1, text2 string) []string {
...
if (condition) {
return nil // That's the final code path)
}
...
}
is returning []string(nil)
instead of nil. At first, I thought that perhaps returning nil
in a function with a particular return type would just return an instance of a zero-value for that type. But then I tried a simple test and that is not the case.
Does anybody know why would nil
return an empty string slice?
Nil is not a type. It is a description of the zero value for maps, chans, pointers, functions, slices, and interfaces.
When you put "nil" in your program, go gives it a type depending on the context. For the most part, you never need to explicitly type your nil. This is no exception, the compiler knows it must be a []string(nil) because the type returned is []string.
A nil string slice is a slice with no backing array and a length/capacity of zero. You may compare it to the literal "nil" and can get its length and capacity. It is a []string, just empty. If you wish to have an empty []string that is not nil, return []string{}. This creates a backing array (of length zero) and makes it no longer equivalent to nil.
I think maybe you are being confused by the output of print. (playground link)
package main
import "fmt"
func f() []string {
return nil // That's the final code path)
}
func main() {
result := f()
fmt.Printf("result = %v
", result)
fmt.Printf("result = %v
", result == nil)
}
Which produces
result = []
result = true
So I think the output really is nil
I believe I know what's going on. The assert library I am using (github.com/bmizerany/assert) is using internally a reflect.DeepEqual
.
The return value of func halfMatch(text1, text2 string) []string
is always of type []string
, but if it returns nil
and is compared to a nil
value via the ==
operator, it will return true
. However, if reflect.DeepEqual
is used, the type will matter and it won't consider both values the same.
Go will return an enpty slice if condition is true.
There is a problem with your "test" because if you try to compare [] with nil, you get true. I have modified your test to show you what I mean
package main
import "fmt"
func main() {
//fmt.Println(test1("") == nil)
fmt.Println(test1("")) // prints []
}
func test1(text1 string) []string {
if len(text1) > 0 {
return []string{text1}
}
return nil
}