我关注的是https://tour.golang.org/moretypes/10示例 我修改了代码,期望获得相同的结果。我没有。这是一个错误,还是文档错误?旅游状态
nil切片的长度和容量为0.
我的y变量的长度和容量为0.
package main
import "fmt"
func myPrint(z []int) {
fmt.Println(z, len(z), cap(z))
if z == nil {
fmt.Println("nil!")
}
}
func main() {
var z []int
y := []int {}
myPrint(z)
myPrint(y)
}
这是我的输出。
[] 0 0
nil!
[] 0 0
我期待第二次" nil"〜为什么我没有得到它?
答案 0 :(得分:13)
您引用的文档指出一个nil切片的长度和容量为0,但不是每个切片的长度和零容量是零切片。 The specification仅表示未初始化切片的值为nil。
这样可以方便地在未初始化(nil)的切片上支持len
和cap
。否则我们需要首先检查非零,以避免恐慌。 (这也适用于其他内置类型,如地图或频道。)
就fmt.Print
输出而言,行为的差异类似于打印未初始化(零)指针与指向空结构的指针:
var s *struct{} // uninitialised pointer
fmt.Println(s) // <nil>
s = &struct{}{} // pointer to an empty structure
fmt.Println(s) // &{}
答案 1 :(得分:7)
在这种情况下:
var z []int
您已声明变量z
,但未对其进行初始化。
在这种情况下:
y := []int {}
您声明并初始化它,将其设置为空切片。长篇大论写第二个表达式使得两个表达式之间的区别更加清晰:
var y []int = []int {}
答案 2 :(得分:7)
nil
对empty
切片如果我们想到这样的切片:
[pointer] [length] [capacity]
然后:
nil slice: [nil][0][0]
empty slice: [addr][0][0] // it points to an address
来自:“开始行动”一书:
零切片
当您想要表示不存在的切片时,它们很有用,例如在返回切片的函数中发生异常时。
// Create a nil slice of integers. var slice []int
空切片
当您想要表示空集合时,例如当数据库查询返回零结果时,空切片很有用。
// Use make to create an empty slice of integers. slice := make([]int, 0) // Use a slice literal to create an empty slice of integers. slice := []int{}
无论您使用的是nil切片还是空切片,内置函数
append
,len
和cap
的工作方式都相同。
package main
import (
"fmt"
)
func main() {
var nil_slice []int
var empty_slice = []int{}
fmt.Println(nil_slice == nil, len(nil_slice), cap(nil_slice))
fmt.Println(empty_slice == nil, len(empty_slice), cap(empty_slice))
}
打印:
true 0 0
false 0 0
答案 3 :(得分:5)
您的y
变量不是切片的零值。它是通过空切片文字分配的。
// both of these allocate a slice
y := []int{}
z := []int{1, 2, 3}
答案 4 :(得分:0)
nil slice的长度和容量为0,没有底层数组。
var s [] string =&gt;没有底层数组 var s = [] string =&gt;创建一个底层数组,但他的长度是0。