Go slice

The length of a Go array cannot be changed, making it less suitable for certain scenarios. Therefore, Go provides a flexible and powerful built-in type: Slice (similar to a dynamic array), which allows appending elements, potentially increasing the slice's capacity during appending.

var variableName []DataType
  1. A slice is a reference to an array, making it a reference type. However, a slice itself is a struct, and its value is passed by copy.
  2. The length of a slice can change, so a slice can be seen as a dynamic array.
  3. The traversal method for a slice is the same as that for an array.
  4. If slice == nil, then both len(slice) and cap(slice) will result in 0.

Slice Definition

Regular Definition

    var s1 []type
or
    s1 := []type{}

Using make

    var s2 []type = make([]type, length, capacity) //length is the length of the array and also the initial length of the slice
or
    s2 := make([]type, length, capacity) //capacity is an optional parameter used to specify the capacity

Slice Initialization

OperationDescription
s[n]Element at index n
s[:]Slice from 0 to len(s)-1
s[startIndex:]Slice from startIndex to len(s)-1
s[startIndex:endIndex]Slice from startIndex to endIndex-1,len = endIndex - startIndex
s[:endIndex]Slice from 0 to endIndex-1
len(s)Length: The number of elements in the slice
cap(s)Capacity: The maximum number of elements the slice can hold without reallocating memory

 

s := []int{9, 8, 7, 6, 5, 4, 3, 2, 1, 0}
s2 := s[:]
s3 := s[1:]
s4 := s[:8]
s5 := s[1:8]
fmt.Println(s2, s3, s4, s5)

#[9 8 7 6 5 4 3 2 1 0] [8 7 6 5 4 3 2 1 0] [9 8 7 6 5 4 3 2] [8 7 6 5 4 3 2]

Appending to a Slice

append adds elements to the end of a slice and returns the new slice object.

#func append(slice []Type, elems ...Type) []Type

s := []int{9, 8, 7, 6, 5, 4, 3, 2, 1, 0}
s2 := append(s, -1)
fmt.Println(s2)

#[9 8 7 6 5 4 3 2 1 0 -1]

When the slice's capacity is exceeded (exceeded slice.cap), a new slice (with a new memory address) is created, the content of the old slice is copied to the new slice, new_slice_cap = 2*old_slice_cap + N  (where N is an integer multiple of 2), until the new slice can accommodate all elements.

s := []int{9, 8, 7, 6}
s3 := s[:3]
fmt.Println("old slice:", s3, "old 1st item address:", &s3[0], "len", len(s3), "cap:", cap(s3))

s3 = append(s3, 10, 11, 12, 13, 14, 15, 16)
fmt.Println("new slice:", s3, "new 1st item address:", &s3[0], "len", len(s3), "cap:", cap(s3))

#old slice: [9 8 7] old 1st item address: 0xc0003dc960 len 3 cap: 4
#new slice: [9 8 7 10 11 12 13 14 15 16] new 1st item address: 0xc00002b2c0 len 10 cap: 10

Copying Slices

Copies elements from a source slice to a destination slice. If the destination slice is shorter than the source slice, only as many elements as fit into the destination slice are copied. Elements at corresponding positions in the destination slice are overwritten.

#func copy(dst []Type, src []Type) int

s1 := []int{1, 2, 3, 4, 5}
fmt.Println("slice s1:", s1)

s2 := make([]int, 10)
fmt.Println("slice s2:", s2)

s3 := []int{10, 9, 8, 7}
fmt.Println("slice s3:", s3)

copy(s2, s1)
copy(s3, s1)
fmt.Println("copied slice s1:", s1)
fmt.Println("copied slice s2:", s2)
fmt.Println("copied slice s3:", s3)

#slice s1: [1 2 3 4 5]
#slice s2: [0 0 0 0 0 0 0 0 0 0]
#slice s3: [10 9 8 7]
#copied slice s1: [1 2 3 4 5]
#copied slice s2: [1 2 3 4 5 0 0 0 0 0]
#copied slice s3: [1 2 3 4]

Slices Traversal

for key, val := range s1 {
    //...  
}

Strings and slices

At its core, a string is just a byte array, therefore, it can also be sliced.

str1 := "hello world"
s1 := str1[0:5]
fmt.Println(s1)

str2 := "你好,世界!"
s := []rune(str2)
s[3] = '闪'
s[4] = '光'
s[5] = '创'
s = append(s, '世')
fmt.Println(string(s))

#hello
#你好,闪光创世

 

Take a break

👉👉👉 【BTTH Year EP105】Xiao Yan refined the Ancient Phoenix Blood Essence, then talked with Elder Feng