切片的零值不是 nil
The zero value of a slice is not nil
我正在效仿这个例子https://tour.golang.org/moretypes/10
我修改了期望得到相同结果的代码。我没有。这是错误还是文档错误?巡演状态
A nil slice has a length and capacity of 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"~为什么我没有得到它?
您的 y
变量 不是 切片的零值。它是通过空切片文字分配的。
// both of these allocate a slice
y := []int{}
z := []int{1, 2, 3}
您引用的文档指出 nil 切片的长度和容量为 0, 但不是 每个 切片的长度和零容量是一个 nil 切片。 The specification 仅表示 未初始化 切片的值为 nil。
这是为了方便在未初始化 (nil) 的切片上支持 len
和 cap
。否则我们需要先检查非零以避免恐慌。 (这也适用于其他内置类型,如地图或通道。)
就 fmt.Print
输出而言,行为上的差异类似于打印未初始化 (nil) 指针与指向空结构的指针:
var s *struct{} // uninitialised pointer
fmt.Println(s) // <nil>
s = &struct{}{} // pointer to an empty structure
fmt.Println(s) // &{}
在这种情况下:
var z []int
你已经声明了一个变量z
但你没有初始化它。
在这种情况下:
y := []int {}
您声明并初始化了它,您将它设置为一个空切片。把第二个表达式写得比较长,两个表达式的区别就更清楚了:
var y []int = []int {}
nil
对比 empty
切片
如果我们想到这样的切片:
[pointer] [length] [capacity]
然后:
nil slice: [nil][0][0]
empty slice: [addr][0][0] // it points to an address
From: "Go in action" book:
nil slice
They’re useful when you want to represent a slice that doesn’t exist, such as when an exception occurs in a function that returns a slice.
// Create a nil slice of integers.
var slice []int
empty slice
Empty slices are useful when you want to represent an empty collection, such as when a database query returns zero results.
// 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{}
Regardless of whether you’re using a nil slice or an empty slice, the built-in functions append
, len
, and cap
work the same.
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
A nil slice has a length and capacity of 0 and has no underlying array.
var s []string => 无底层数组
var s = []string => 创建一个底层数组但是他的长度是 0.
我正在效仿这个例子https://tour.golang.org/moretypes/10 我修改了期望得到相同结果的代码。我没有。这是错误还是文档错误?巡演状态
A nil slice has a length and capacity of 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"~为什么我没有得到它?
您的 y
变量 不是 切片的零值。它是通过空切片文字分配的。
// both of these allocate a slice
y := []int{}
z := []int{1, 2, 3}
您引用的文档指出 nil 切片的长度和容量为 0, 但不是 每个 切片的长度和零容量是一个 nil 切片。 The specification 仅表示 未初始化 切片的值为 nil。
这是为了方便在未初始化 (nil) 的切片上支持 len
和 cap
。否则我们需要先检查非零以避免恐慌。 (这也适用于其他内置类型,如地图或通道。)
就 fmt.Print
输出而言,行为上的差异类似于打印未初始化 (nil) 指针与指向空结构的指针:
var s *struct{} // uninitialised pointer
fmt.Println(s) // <nil>
s = &struct{}{} // pointer to an empty structure
fmt.Println(s) // &{}
在这种情况下:
var z []int
你已经声明了一个变量z
但你没有初始化它。
在这种情况下:
y := []int {}
您声明并初始化了它,您将它设置为一个空切片。把第二个表达式写得比较长,两个表达式的区别就更清楚了:
var y []int = []int {}
nil
对比 empty
切片
如果我们想到这样的切片:
[pointer] [length] [capacity]
然后:
nil slice: [nil][0][0]
empty slice: [addr][0][0] // it points to an address
From: "Go in action" book:
nil slice
They’re useful when you want to represent a slice that doesn’t exist, such as when an exception occurs in a function that returns a slice.
// Create a nil slice of integers. var slice []int
empty slice
Empty slices are useful when you want to represent an empty collection, such as when a database query returns zero results.
// 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{}
Regardless of whether you’re using a nil slice or an empty slice, the built-in functions
append
,len
, andcap
work the same.
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
A nil slice has a length and capacity of 0 and has no underlying array.
var s []string => 无底层数组 var s = []string => 创建一个底层数组但是他的长度是 0.