string和Slice的长度

string

// go runtime
type stringStruct struct {
	str unsafe.Pointer
	len int
}

1
2
3
4
5
6

string 的长度就是字符串或者string切片的长度

slice

// go runtime
type slice struct {
	array unsafe.Pointer
	len   int
	cap   int
}
1
2
3
4
5
6

Slice 的长度是切片长度 但是Slice的容量是切片开始位置到原Slice的容量结束位置

对于Slice切片的操作会作用于底层数组

更有趣的一些事情是 append 操作如果没有超过原Slice的容量的话 会直接修改值

如果超过了 就会重新分配(先检测 再分配赋值)

len&cap

func main() {
	var v = "12345678"
	fmt.Printf("len of v:%d=8\tv[1:]:%d=8-1\tv[1:3]:%d=3-1\n", len(v), len(v[1:]), len(v[1:3]))
	var s = []int{1, 2, 3, 4, 5, 6, 7, 8}
	fmt.Printf("s len:%d=8,cap:%d=8\n", len(s), cap(s))
	fmt.Printf("s[1:] len:%d=8-1,cap:%d=8-1\n", len(s[1:]), cap(s[1:]))
	fmt.Printf("s[2:7] len:%d=7-2,cap:%d=8-2\n", len(s[2:7]), cap(s[2:7]))
	// how about append the slice of Slice
	it := append(s[2:7], 9)
	fmt.Printf("raw data:%d,addr:%p\nin it v:%d,addr:%p\n", s[7], &s[7], it[5], &it[5])
	fmt.Printf("s[2:7] len:%d=7-2,cap:%d=8-2\n", len(s[2:7]), cap(s[2:7]))
	fmt.Printf("it len:%d=7-2+1,cap:%d=8-2\n", len(it), cap(it))
	// something more interesting
	it = append(s[3:4], 10, 11, 12)
	fmt.Println("s:", s)
	fmt.Println("it:", it)
	fmt.Printf("raw data:%d,addr:%p\nin it v:%d,addr:%p\n", s[7], &s[7], it[0], &it[0])
	it = append(s[6:7], 20, 21, 22)
	fmt.Println("s:", s)
	fmt.Println("it:", it)
	fmt.Printf("raw data:%d,addr:%p\nin it v:%d,addr:%p\n", s[7], &s[7], it[0], &it[0])
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

各部分运行结果如下

len of v:8=8    v[1:]:7=8-1     v[1:3]:2=3-1
s len:8=8,cap:8=8
s[1:] len:7=8-1,cap:7=8-1
s[2:7] len:5=7-2,cap:6=8-2
1
2
3
4
raw data:9,addr:0xc0000c0078
in it v:9,addr:0xc0000c0078
s[2:7] len:5=7-2,cap:6=8-2
it len:6=7-2+1,cap:6=8-2
1
2
3
4
s: [1 2 3 4 10 11 12 9]
it: [4 10 11 12]
raw data:9,addr:0xc0000c0078
in it v:4,addr:0xc0000c0058
s: [1 2 3 4 10 11 12 9]
it: [12 20 21 22]
raw data:9,addr:0xc0000c0078
in it v:12,addr:0xc0000be020
1
2
3
4
5
6
7
8