博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Go语言模型:切片slice的底层实现
阅读量:4208 次
发布时间:2019-05-26

本文共 1962 字,大约阅读时间需要 6 分钟。

Go语言的切片实现可以看runtime的slice.go文件,切片是Go语言内置的数据结构,编译器识别到切片语法操作时会自动调用runtime对应底层实现,所以用起来就非常方便,这也是语言级的实现比库实现的优势。

可以通过一个例子来看切片的内存模型:

// go version: 1.7package mainimport (    "fmt"    "reflect"    "unsafe")// GDB时,避免局部变量可能会被优化,全局变量方便GDB查看进程对应内存// 编译时加调试信息并去掉优化: go build -gcflags "-N -l" hi.govar (    a = [...]int{
1, 2, 3, 4, 5} // 数组 b = a[2:4] // 切片 --> 通过数组+[:]语法生成切片 c = &a // 指针指向数组 d = []int{
1, 2, 3} // 切片 --> 直接初始化切片[]Type{data..}语法)// runtime: 拷贝自slice.go的私有结构体, 64位操作系统就是24个字节大小type slice struct {
array unsafe.Pointer len int cap int}func main() {
fmt.Println("&a[2]", &a[2]) // &a[2] 0xf8270 fmt.Println("len", len(b), "cap", cap(b)) // len 2 cap 3 fmt.Println(reflect.TypeOf(a), unsafe.Sizeof(a)) // [5]int 40 fmt.Println(reflect.TypeOf(b), unsafe.Sizeof(b)) // []int 24 fmt.Println(reflect.TypeOf(c), unsafe.Sizeof(c)) // *[5]int 8 fmt.Printf("%+v\n", *(*slice)(unsafe.Pointer(&b))) // {array:0xf8270 len:2 cap:3} fmt.Printf("%+v\n", *(*slice)(unsafe.Pointer(&d))) // {array:0xf8090 len:3 cap:3} // append 出发自动扩容,生成一个新的切片实例 fmt.Println(unsafe.Pointer(&d)) // 0xfa100 d = append(d, 4) fmt.Printf("%+v\n", *(*slice)(unsafe.Pointer(&d))) // {array:0xc4200121e0 len:4 cap:6} fmt.Println(unsafe.Pointer(&d)) // 0xfa100}

内置函数 append 会出发切片的扩容,这个跟C++ vector实现原理有点类似,申请个新的底层数组,拷贝原有数据过去。

// 切片的append操作,返回一个新切片slice = append(slice, elem1, elem2)slice = append(slice, anotherSlice...)// runtime src: slice.go, @fun: growslice// 扩容策略: 小于1024,每次扩容*2; 大于1024,每次扩容*1.25newcap := old.capdoublecap := newcap + newcapif cap > doublecap {
newcap = cap} else {
if old.len < 1024 {
newcap = doublecap } else {
for newcap < cap {
newcap += newcap / 4 } }}

切片使用起来非常的方便,这都得益于go语言语法级对切片的支持,很容用[:]之类的写法来生成切片实例。还有go的协程也是类似,而库级别的实现远远没有语法级别的支持用起来方便,这都是go的优势所在。

转载地址:http://qbqli.baihongyu.com/

你可能感兴趣的文章
0226 rest接口设计
查看>>
0228 我的潘多拉
查看>>
0302 中台落地前概念和思考
查看>>
0228 我的潘多拉
查看>>
0302 中台落地前概念和思考
查看>>
0219 springmvc-拦截器和响应增强
查看>>
0308 软件系统的非功能需求
查看>>
0308 软件系统的非功能需求
查看>>
0309 软件基本原理1
查看>>
0312 java接口测试三棱军刺rest-assured
查看>>
0318 guava并发工具
查看>>
0312 java接口测试三棱军刺rest-assured
查看>>
中台之中台的设计
查看>>
mysql之事务
查看>>
中台之交付
查看>>
面试刷题1: 简要介绍java平台?java是解释执行的吗?
查看>>
面试刷题2:Exception和Error的区别?
查看>>
面试刷题3:final finally finalize区别?
查看>>
面试刷题4:强 弱 软 幻象 引用的区别?
查看>>
面试刷题5:String StringBuffer StringBuilder区别?
查看>>