Home > Article > Backend Development > nil slice, non-nil slice, empty slice in Go language
php editor Xiaoxin brings you an introduction to the slice types in the Go language. In Go language, slices have three states: nil slice, non-nil slice and empty slice. These three slicing states have different meanings and characteristics when used. Understanding the differences between these slice types will help us better understand and use the slice function in the Go language. Next, let’s explore the specific features and uses of these three slice types.
I am new to Go programming. I read in a Go programming book that a slice consists of three parts: a pointer to the array, the length, and the capacity.
I'm confused about the following:
Can anyone tell me if nil and empty slice are the same thing? If both are different then please tell me what is the difference between these two? How to test if a slice is empty? Also, what value does a pointer hold in a non-zero slice with zero length and capacity?
nil
is not the same as an empty slice (capacity 0), but their observable behavior is the same (almost always). I mean:
len()
and cap()
functionsfor range
override them (will be 0 iterations) Check out this simple example (one nil
slice and 2 non-nil
empty slices):
var s1 []int // nil slice s2 := []int{} // non-nil, empty slice s3 := make([]int, 0) // non-nil, empty slice fmt.Println("s1", len(s1), cap(s1), s1 == nil, s1[:], s1[:] == nil) fmt.Println("s2", len(s2), cap(s2), s2 == nil, s2[:], s2[:] == nil) fmt.Println("s3", len(s3), cap(s3), s3 == nil, s3[:], s3[:] == nil) for range s1 {} for range s2 {} for range s3 {}
Output (try it on Go Playground):
s1 0 0 true [] true s2 0 0 false [] false s3 0 0 false [] false
(Note that slicing a nil
slice produces a nil
slice, and slicing a non-nil
slice produces a non-nil
slice.)
With the exception that you can only tell the difference by comparing the slice value to the predeclared identifier nil
, they all behave identically in other respects. But be aware that many packages do compare slices to nil
and may do things differently based on that (e.g. encoding/json
and fmt
packages).
The only difference is converting the slice to an array pointer (added to the language in Go 1.17). Converting a non-nil
slice to an array pointer produces a non-nil
pointer, and converting a nil
slice to an array pointer produces a nil
pointer.
To determine if a slice is empty, simply compare its length to 0
: len(s) == 0
. Whether it's a nil
slice or a non-nil
slice, it doesn't matter whether it has a positive capacity; if it has no elements, it's empty.
s := make([]int, 0, 100) fmt.Println("Empty:", len(s) == 0, ", but capacity:", cap(s))
Print (try it on Go Playground):
Empty: true , but capacity: 100
Slice values are represented by structures defined in reflect.SliceHeader
:
type SliceHeader struct { Data uintptr Len int Cap int }
For a nil
slice, the structure will have its zero value, i.e. all its fields will have zero values, i.e.: 0
.
If the capacity and length of the non-nil
slice is equal to the 0
, Len
and Cap
fields, it is most likely 0
, but the Data
pointer may not be. It won't , that's what differentiates it from a nil
slice. It will point to a zero-sized underlying array.
Please note that the Go specification allows values of different types with size 0 to have the same memory address. Specifications: System Notes: Size and Alignment Guarantees:
让我们检查一下。为此,我们调用 unsafe
包的帮助,并“获取” reflect.SliceHeader
结构“视图” “我们的切片值:
var s1 []int s2 := []int{} s3 := make([]int, 0) fmt.Printf("s1 (addr: %p): %+8v\n", &s1, *(*reflect.SliceHeader)(unsafe.Pointer(&s1))) fmt.Printf("s2 (addr: %p): %+8v\n", &s2, *(*reflect.SliceHeader)(unsafe.Pointer(&s2))) fmt.Printf("s3 (addr: %p): %+8v\n", &s3, *(*reflect.SliceHeader)(unsafe.Pointer(&s3)))
输出(在 Go Playground 上尝试一下):
s1 (addr: 0x1040a130): {Data: 0 Len: 0 Cap: 0} s2 (addr: 0x1040a140): {Data: 1535812 Len: 0 Cap: 0} s3 (addr: 0x1040a150): {Data: 1535812 Len: 0 Cap: 0}
我们看到了什么?
nil
切片具有 0
数据指针s2
和 s3
切片确实具有相同的数据指针,共享/指向相同的 0 大小的内存值The above is the detailed content of nil slice, non-nil slice, empty slice in Go language. For more information, please follow other related articles on the PHP Chinese website!