0%

Slice in Golang

Blogs

Go Slices: usage and internals
Arrays, slices (and strings): The mechanics of 'append'

Details

make

Look up in $GOROOT/src/runtime/slice.go:makeslice.

append

https://stackoverflow.com/a/33405824/13133551

slicing

The length is the number of elements referred to by the slice. The capacity is the number of elements in the underlying array (beginning at the element referred to by the slice pointer).

copy

Look up in $GOROOT/src/runtime/slice.go:slicecopy.

The copy function supports copying between slices of different lengths (it will copy only up to the smaller number of elements). In addition, copy can handle source and destination slices that share the same underlying array, handling overlapping slices correctly.

Codes

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
package main

import (
"os"

logger "github.com/sirupsen/logrus"
"github.com/x-cray/logrus-prefixed-formatter"
)

func assertPanic(v bool) {
if !v {
panic("v is not true")
}
}

func init() {
logger.SetFormatter(&prefixed.TextFormatter{
TimestampFormat: "2006-01-02 15:04:05",
FullTimestamp: true,
ForceFormatting: true,
DisableColors: true,
})
logger.SetOutput(os.Stdout)
logger.SetLevel(logger.DebugLevel)
}

func sliceCopy() {
logger.Infof("in sliceCopy")
s := make([]int, 0)
for i := 0; i < 10; i++ {
s = append(s, i)
}

c := make([]int, 0)
copy(c, s)
logger.Infof("c: %v", c)

c = make([]int, 5)
copy(c, s)
logger.Infof("c: %v", c)

c = make([]int, 15)
copy(c, s)
logger.Infof("c: %v", c)

c = make([]int, 5, 20)
copy(c, s)
logger.Infof("c: %v", c)

c[0] = 256
logger.Infof("c: %v, s: %v", c, s)
}

func sliceAppend() {
logger.Infof("in sliceAppend")
s := make([]int, 0)
for i := 0; i < 10; i++ {
s = append(s, i)
logger.Infof("after appending: %v, len(s): %v, cap(s): %v", i, len(s), cap(s))
}
for i := 0; i < 10; i++ {
l := len(s)
c := cap(s)
after := append(s, i)
if l == c {
assertPanic(&s[0] != &after[0])
assertPanic(s[0] == after[0])

s[0] += 8
assertPanic(s[0] != after[0])
} else {
assertPanic(&s[0] == &after[0])
assertPanic(s[0] == after[0])

s[0] += 8
assertPanic(s[0] == after[0])
}
s = after
}
}

func resultOfAppend() {
logger.Infof("in resultOfAppend")
s := make([]int, 0, 64)
s = append(s, 1, 2, 3, 4, 5)

x := append(s, 16)
assertPanic(x[5] == 16)

y := append(s, 32)
assertPanic(x[5] == 32)
assertPanic(y[5] == 32)
}

func slicing() {
logger.Infof("in slicing")
s := make([]int, 0, 6)
s = append(s, 1, 2, 3, 4, 5)

y := s[1:3]
assertPanic(len(y) == 2)
assertPanic(cap(y) == 5)

y[0] = 10
assertPanic(s[1] == 10)

y = append(y, 8)
assertPanic(s[3] == 8)
assertPanic(y[2] == 8)

s[3] = 32
assertPanic(y[2] == 32)
}

func main() {
sliceCopy()
sliceAppend()
resultOfAppend()
slicing()
}

Result:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[2020-03-27 16:04:59]  INFO in sliceCopy
[2020-03-27 16:04:59] INFO c: []
[2020-03-27 16:04:59] INFO c: [0 1 2 3 4]
[2020-03-27 16:04:59] INFO c: [0 1 2 3 4 5 6 7 8 9 0 0 0 0 0]
[2020-03-27 16:04:59] INFO c: [0 1 2 3 4]
[2020-03-27 16:04:59] INFO c: [256 1 2 3 4], s: [0 1 2 3 4 5 6 7 8 9]
[2020-03-27 16:04:59] INFO in sliceAppend
[2020-03-27 16:04:59] INFO after appending: 0, len(s): 1, cap(s): 1
[2020-03-27 16:04:59] INFO after appending: 1, len(s): 2, cap(s): 2
[2020-03-27 16:04:59] INFO after appending: 2, len(s): 3, cap(s): 4
[2020-03-27 16:04:59] INFO after appending: 3, len(s): 4, cap(s): 4
[2020-03-27 16:04:59] INFO after appending: 4, len(s): 5, cap(s): 8
[2020-03-27 16:04:59] INFO after appending: 5, len(s): 6, cap(s): 8
[2020-03-27 16:04:59] INFO after appending: 6, len(s): 7, cap(s): 8
[2020-03-27 16:04:59] INFO after appending: 7, len(s): 8, cap(s): 8
[2020-03-27 16:04:59] INFO after appending: 8, len(s): 9, cap(s): 16
[2020-03-27 16:04:59] INFO after appending: 9, len(s): 10, cap(s): 16
[2020-03-27 16:04:59] INFO in resultOfAppend
[2020-03-27 16:04:59] INFO in slicing