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()
andcap()
functionsfor range
override them (will be 0 iterations)Check out this simple example (onenil
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 onGo Playground):
s1 0 0 true [] true s2 0 0 false [] false s3 0 0 false [] false
(Note that slicing anil
slice produces anil
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 identifiernil
, they all behave identically in other respects.But be aware that many packages do compare slices tonil
and may do things differently based on that (e.g.encoding/json
andfmt
packages).
The only difference isconverting the slice to an array pointer(added to the language inGo 1.17). Converting a non-nil
slice to an array pointer produces a non-nil
pointer, and converting anil
slice to an array pointer produces anil
pointer.
To determine if a slice is empty, simply compare its length to0
:len(s) == 0
. Whether it's anil
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 onGo Playground):
Empty: true , but capacity: 100
Slice values are represented by structures defined inreflect.SliceHeader
:
type SliceHeader struct { Data uintptr Len int Cap int }
For anil
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 the0
,Len
andCap
fields, it is most likely0
, but theData
pointer may not be. Itwon't, that's what differentiates it from anil
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!