英文:
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
,类型将会有所影响,它不会认为两个值相同。
英文:
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.
答案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
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论