无法返回nil,但可以返回切片的零值。

huangapple go评论89阅读模式
英文:

Can't return nil, but zero value of slice

问题

我遇到了一个函数的情况,其中包含以下代码:

func halfMatch(text1, text2 string) []string {
    ...
    if (condition) {
         return nil // 这是最终的代码路径)
    }
    ...
}

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

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

英文:

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?

答案1

得分: 17

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

当你在程序中使用"nil"时,根据上下文,Go会给它一个类型。在大多数情况下,你不需要显式地为nil指定类型。这也不例外,编译器知道它必须是[]string(nil),因为返回的类型是[]string。

一个nil字符串切片是一个没有支持数组的切片,长度/容量为零。你可以将它与字面值"nil"进行比较,并可以获取它的长度和容量。它是一个[]string,只是空的。如果你希望有一个不是nil的空[]string,可以返回[]string{}。这将创建一个支持数组(长度为零),并使其不再等同于nil。

英文:

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.

答案2

得分: 2

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

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

带有测试的playground链接

英文:

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.

playgound link with the test

答案3

得分: 0

我认为你可能被print的输出所迷惑了。(playground链接)

package main

import "fmt"

func f() []string {
    return nil // 这是最终的代码路径
}
func main() {
    result := f()
    fmt.Printf("result = %v\n", result)
    fmt.Printf("result = %v\n", result == nil)
}

产生的输出是

result = []
result = true

所以我认为输出确实是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\n", result)
	fmt.Printf("result = %v\n", result == nil)
}

Which produces

result = []
result = true

So I think the output really is nil

答案4

得分: 0

如果条件为真,Go将返回一个空切片。

你的“test”有一个问题,因为如果你尝试将[]与nil进行比较,你会得到true。我修改了你的测试来展示我的意思。

package main
import "fmt"

func main() {
    //fmt.Println(test1("") == nil)  
    fmt.Println(test1("")) // 打印 []
}

func test1(text1 string) []string {
    if len(text1) > 0 {
        return []string{text1}
    }
    return nil
}
英文:

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
}

huangapple
  • 本文由 发表于 2012年12月20日 17:58:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/13969492.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定