源代码
runtime/slice.go
1 2 3 4 5
| type slice struct { array unsafe.Pointer len int cap int }
|
2行 指向底层数组的指针
3行 长度大小
4行 容量大小

字面量创建切片
1 2 3 4 5 6 7 8
| package main
import "fmt"
func main() { s := []string{"碳烤生蚝", "红烧肉", "帝王蟹"} fmt.Println(s) }
|
go build -gcflags -S main.go
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| ... 0x0018 00024 (/menu7/main.go:6) MOVD $type.[3]string(SB), R0 0x0020 00032 (/menu7/main.go:6) PCDATA $1, ZR 0x0020 00032 (/menu7/main.go:6) CALL runtime.newobject(SB) 0x0024 00036 (/menu7/main.go:6) MOVD $12, R1 0x0028 00040 (/menu7/main.go:6) MOVD R1, 8(R0) 0x002c 00044 (/menu7/main.go:6) MOVD $go.string."碳烤生蚝"(SB), R1 0x0034 00052 (/menu7/main.go:6) MOVD R1, (R0) 0x0038 00056 (/menu7/main.go:6) MOVD $9, R1 0x003c 00060 (/menu7/main.go:6) MOVD R1, 24(R0) 0x0040 00064 (/menu7/main.go:6) MOVD $go.string."红烧肉"(SB), R2 0x0048 00072 (/menu7/main.go:6) MOVD R2, 16(R0) 0x004c 00076 (/menu7/main.go:6) MOVD R1, 40(R0) 0x0050 00080 (/menu7/main.go:6) MOVD $go.string."帝王蟹"(SB), R1 0x0058 00088 (/menu7/main.go:6) MOVD R1, 32(R0) ...
|
2行 创建3个string大小的数组
4行 创建slice结构体
make函数创建切片
1 2
| s2 := make([]string, 5) fmt.Println(s2)
|
runtime/slice.go
1 2 3
| func makeslice(et *_type, len, cap int) unsafe.Pointer { ... }
|
切片扩容
可以容纳新元素

可以看到上图,还有一个空位置,那么再来一个元素是可以放进去的,没有问题。
新增元素多余剩余空间

可以看到上图,原本的数组不够放入新元素,那么就会新找一个连续的位置,存放新的数组,并且把原来数组内容复制过去,再新增内容。
切片长度<1024,扩容的容量会翻倍
切片长度>1024,扩容的容量增加25%
切片扩容的时候,并发不安全,有必要考虑加锁。
runtime/slice.go
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| func growslice(et *_type, old slice, cap int) slice { ... newcap := old.cap doublecap := newcap + newcap if cap > doublecap { newcap = cap } else { const threshold = 256 if old.cap < threshold { newcap = doublecap } else { for 0 < newcap && newcap < cap { newcap += (newcap + 3*threshold) / 4 } if newcap <= 0 { newcap = cap } } } ... }
|
如何学习Go语言微服务,快速步入架构师
添加微信 |
公众号更多内容 |
 |
 |