不能返回nil,而是切片的零值

时间:2012-12-20 09:58:27

标签: go

我遇到的函数包含以下代码:

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

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

有人知道为什么nil会返回空字符串切片吗?

4 个答案:

答案 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,则类型将很重要,并且不会将两个值都视为相同。

playgound link with the test

答案 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
}