2

我遇到的情况是具有以下代码的函数:

func halfMatch(text1, text2 string) []string {
    ...
    if (condition) {
         return nil // That's the final code path)
    }
    ...
}

正在返回[]string(nil)而不是 nil。起初,我认为返回nil具有特定返回类型的函数可能只会返回该类型的零值实例。但后来我尝试了一个简单的测试,但事实并非如此。

有谁知道为什么会nil返回一个空字符串切片?

4

4 回答 4

16

Nil 不是类型。它是对映射、通道、指针、函数、切片和接口的零值的描述。

当你在你的程序中输入“nil”时,go 会根据上下文给它一个类型。在大多数情况下,您永远不需要显式键入您的 nil。这也不例外,编译器知道它必须是 []string(nil),因为返回的类型是 []string。

nil 字符串切片是没有后备数组且长度/容量为零的切片。您可以将其与文字“nil”进行比较,并可以得到它的长度和容量。它是一个 [] 字符串,只是空的。如果您希望有一个不为 nil 的空 []string,请返回 []string{}。这会创建一个支持数组(长度为零)并使其不再等价于 nil。

于 2012-12-20T14:07:04.007 回答
1

我相信我知道发生了什么。我正在使用的断言库(github.com/bmizerany/assert)在内部使用reflect.DeepEqual.

的返回值func halfMatch(text1, text2 string) []string始终是 type []string,但如果它返回nil并通过运算符与一个nil值进行比较==,它将返回true。但是,如果reflect.DeepEqual使用,则类型很重要,并且不会认为两个值相同。

与测试的游乐场链接

于 2012-12-20T11:02:22.680 回答
0

我想你可能对 print 的输出感到困惑。(游乐场链接

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

于 2012-12-20T10:20:05.343 回答
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
}
于 2012-12-20T16:09:03.230 回答