首页 > 解决方案 > Go 中 []Foo(nil) 和 []Foo{} 的区别

问题描述

我是 Go 新手,想知道 和 之间的[]Foo(nil)区别[]Foo{}

(我在我的测试中使用它,我想指定当我的函数出错时,它应该返回nil, err。当我使用时 go linter 会抱怨nilor []Foo{},但在我使用时会起作用[]Foo(nil)。)

我试过的

我查看了 Go 文档和 SO 并找到了 Struct 的东西,Foo{}但不是[]Foo(nil).

当我使用[]Foo{}时,测试失败输出:

expected: []Foo{}
actual  : []Foo(nil)

[]Foo(nil)和的Fmt 输出[]Foo{}是相同的:

fmt.Println([]Foo(nil)) // []
fmt.Println([]Foo(){}) // []
fmt.Printf([]Foo(nil)) // []Foo
fmt.Printf([]Foo(){}) // []Foo

我注意到,如果我只写Foo(nil)(没有[]),那么 linter 就会抱怨cannot convert nil to type Foo.

所以我唯一的猜测是[]Foo(nil)调用某种类型的强制。谁能帮我吗?

标签: arraysgostruct

解决方案


表达式[]Foo(nil)是一个转换。它将无类型的 nil 转换为类型的 nil 切片[]Foo

该表达式[]Foo{}是一个复合文字,它返回一个空切片。它是空的,因为{}.

这可能有助于解释差异:

fmt.Println([]Foo(nil) == nil) // prints true
fmt.Println([]Foo{} == nil)    // prints false

nil 切片没有后备数组。一个空切片有一个长度为 0 的后备数组。

令人困惑的是,fmt 包可以为空切片和零切片输出相同的数据。

如果 nil 切片和空切片之间的区别在您的测试中并不重要,那么使用len(s) == 0. 对于 nil 切片和空切片,此表达式的计算结果均为 true。


推荐阅读