我遇到的函数包含以下代码:
func halfMatch(text1, text2 string) []string {
...
if (condition) {
return nil // That's the final code path)
}
...
}
返回[]string(nil)
而不是nil。起初,我认为在具有特定返回类型的函数中返回nil
可能只返回该类型的零值实例。但后来我尝试了一个简单的test,事实并非如此。
有人知道为什么nil
会返回空字符串切片吗?
答案 0 :(得分:14)
Nil不是一种类型。它描述了地图,chans,指针,函数,切片和接口的零值。
当你在程序中加入“nil”时,go会根据上下文给它一个类型。在大多数情况下,您永远不需要明确键入您的nil。这也不例外,编译器知道它必须是[]字符串(nil),因为返回的类型是[] string。
nil字符串切片是没有后备数组且长度/容量为零的切片。您可以将它与文字“nil”进行比较,并获得其长度和容量。它是一个[]字符串,只是空的。如果你希望有一个非空的[]字符串,请返回[] string {}。这会创建一个支持数组(长度为零)并使其不再等于nil。
答案 1 :(得分:1)
我相信我知道发生了什么。我正在使用的断言库(github.com/bmizerany/assert)在内部使用reflect.DeepEqual
。
func halfMatch(text1, text2 string) []string
的返回值始终为[]string
类型,但如果它返回nil
并通过nil
运算符与==
值进行比较,它将返回true
。但是,如果使用reflect.DeepEqual
,则类型将很重要,并且不会将两个值都视为相同。
答案 2 :(得分:0)
我想也许你对打印输出感到困惑。 (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\n", result)
fmt.Printf("result = %v\n", result == nil)
}
哪个产生
result = []
result = true
所以我认为输出真的是nil
答案 3 :(得分:0)
Go将返回一个enpty切片。
你的“测试”存在问题,因为如果你试图将[]与nil进行比较,你就会得到真的。 我修改了你的测试以向你展示我的意思
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
}