go语言slice的理解
Golang slice
yongsean 作者
2017.02.17 00:07 打开App
创建切片,len、cap、append
b := make([]int, 5)
println(len(b), cap(b)) // 输出结果是:5, 5
fmt.Println(b) // 输出结果是:[0 0 0 0 0]
上述代码是生成默认占用5个0值的切片,下面的输出结果是另一回事
b := make([]int, 0, 5)
println(len(b), cap(b)) // 输出结果是:0, 5
fmt.Println(b) // 输出结果是:[]
上述代码是生成cap长度为5,实际使用长度为0的切片,在指定的cap内进行append操作,是不会发生内存拷贝扩容操作。
b := make([]int, 0, 2)
fmt.Printf("%d, %d, %p\n", len(b), cap(b), b) // 0, 2, 0xc420012190
b = append(b, 1)
b = append(b, 2)
fmt.Printf("%d, %d, %p\n", len(b), cap(b), b) // 2, 2, 0xc420012190
b = append(b, 3)
fmt.Printf("%d, %d, %p\n", len(b), cap(b), b) // 3, 4, 0xc420012198
最后一行输出显示,内存地址跟前2次输出的不一样,并且cap值也在原来的基础上,翻了一倍,相当于做了如下操作:
// mock append
tmp := make([]int, 0, cap(b) * 2) // 是当前的cap值的翻倍
// 复制操作略过。。。
b = tmp
copy
正常的切片copy操作
a := make([]int, 5)
a[0] = 1
a[1] = 2
fmt.Println(a) // [1 2 0 0 0]
b := make([]int, 5)
b[0] = 11
b[1] = 22
b[2] = 33
b[3] = 44
b[4] = 55
fmt.Println(b) // [11 22 33 44 55]
copy(b, a)
fmt.Println(b) // [1 2 0 0 0]
另一个效果
a := make([]int, 5)
a[0] = 1
a[1] = 2
fmt.Println(a) // [1 2 0 0 0]
b := make([]int, 0, 5) // len(b)!=cap(b)
b = append(b, 11)
b = append(b, 22)
fmt.Println(b) // [11, 22]
copy(b, a)
fmt.Println(b) // [1 2]
第三行的输出,只是[1 2],不是[1 2 0 0 0],是对b切片里len(b)长度内的元素进行对应下标复制操作,假如len(b)==0,那输出结果是[]。 这是需要小心的地方,老司机会一不留神搞错,不了解的人那就更难说。
切片的切片
a := make([]int, 5)
a[0] = 1
a[1] = 2
a[2] = 3
a[3] = 4
a[4] = 5
// 原始数据输出
fmt.Printf("%v, %p\n", a, a) // [1 2 3 4 5], 0xc4200141b0
aslice1 := a[1:]
// 第一组输出
fmt.Printf("%v, %p\n", aslice1, aslice1) // [2 3 4 5], 0xc4200141b8
fmt.Println(len(aslice1), cap(aslice1)) // 4 4
aslice2 := a[1:3]
// 第二组输出
fmt.Printf("%v, %p\n", aslice2, aslice2) // [2 3], 0xc4200141b8
fmt.Println(len(aslice2), cap(aslice2)) // 2 4
aslice3 := a[:3]
// 第三组输出
fmt.Printf("%v, %p\n", aslice3, aslice3) // [1 2 3], 0xc4200141b0
fmt.Println(len(aslice3), cap(aslice3)) // 3 5
上面几组输出,粗看没什么,细看还是有值得注意的
每组的len和cap值都不太一样
切片的内存地址不是完全相同
len的值好理解,无异议。
cap的值:
在 第一组输出 中是4,是新切片首地址到原始切片尾地址的个数。
在 第二组输出 中也是4,是新切片首地址到原始切片尾地址的个数
在 第三组输出 中是5,道理如上
内存地址:
原始数据输出的地址和第三组输出的地址一样
第一组输出的地址和第二组输出的地址一样
这样输出的原因是,指向的切片首地址一样。在64位操作系统,int类型占8个字节,第二组输出的地址比第三组输出的地址多8个数值。若有新的切片是如下定义:
aslice4 := a[2:]
fmt.Println("%p\n", aslice4) // 0xc4200141c0
那输出结果是:0xc4200141c0,是 0xc4200141b8+8 的结果
go语言slice的理解的更多相关文章
- Java语言的个人理解
Java语言的个人理解(比价深层次吧) 大四的生活确实十分的奢靡,不锻炼,不读书,几乎就是当一天和尚撞一天钟的生活,太颓废了,还好自己不是这个样子,不过身体确实差了很多,昨天跑了一圈内环(4KM),今 ...
- go语言---slice
go语言---slice https://blog.csdn.net/cyk2396/article/details/78893420 一.数组切片的使用: //1.基于数组创建数组切片 var ar ...
- Go语言Slice作为函数参数详解
Go语言Slice作为函数参数详解 前言 首先要明确Go语言中实质只有值传递,引用传递和指针传递是相对于参数类型来说. 个人认为上诉的结论不对,把引用类型看做对指针的封装,一般封装为结构体,结构体是值 ...
- C 语言指针怎么理解?
对于程序员来说内存可以简化成这样一种东西:<img src="https://pic1.zhimg.com/4d060c3f67c22cd4b07273db00f64708_b ...
- 说说对C语言指针的理解
指针困扰了一些学习编程的人,或许你的老师会告诉你,指针比较难理解. 我当时被老师的话唬住所以学习指针那章的时候都没心情听课.(说得像讲别的内容时我听了似的,开玩笑) 导致了学习链表的时候各种卧槽. * ...
- C语言数据类型的理解
数据类型的定义: 作为一种语言,必然有所谓的语言组成要素,就像日常生活中人们之间的交流一样,首先会有字,字再成词组,再来就是句子,后来呢就是段落等等.当然不同的字,词,句这些在一起,就会有不同的表达效 ...
- GO语言slice详解(结合源码)
一.GO语言中slice的定义 slice 是一种结构体类型,在源码中的定义为: src/runtime/slice.go type slice struct { array unsafe.Point ...
- 由linux内核某个片段(container_of)引发的对于C语言的深入理解
/usr/src/linux-source-3.8.0/drivers/gpu/drm/radeon 这个文件夹以下 去找到这个文件 mkregtable.c 打开,就能够看到了. #define ...
- 有关C++ std::string 类的类型转换 其他语言永远无法理解的伤
最近做了个项目,C++的MFC窗口程序,一个基于dialog的学生-图书管理系统,有一些感触,最后会放上一些项目截图和部分代码提供大家参考.如果有什么好方法和建议欢迎指导. 强类型,为什么这么伤 我知 ...
随机推荐
- [转]mysql常用函数
转自:http://sjolzy.cn/Common-functions-mysql.html 控制流函数 IFNULL(expr1,expr2) 如果expr1不是NULL,IFNULL()返回ex ...
- 利用freemarker导出页面格式复杂的excel
刚开始大家可能会利用poi生成简单的excel,但是遇到需要生成复杂的excel,poi导出excel就比较困难,这时候可以利用freemarker来渲染实现实现生成复杂的excel, 首先,将exc ...
- [ NOI 2002 ] Robot
\(\\\) Description \(\\\) Solution 垃圾语文题毁我青春 这题其实就是重定义了俩函数.... 首先 \(\varphi(1)=0\) . 然后 \(2\) 在计算 \( ...
- 1807. [NOIP2014]寻找道路P2296 寻找道路
题目描述 在有向图G 中,每条边的长度均为1 ,现给定起点和终点,请你在图中找一条从起点到终点的路径,该路径满足以下条件: 1 .路径上的所有点的出边所指向的点都直接或间接与终点连通. 2 .在满足条 ...
- Java 基础入门随笔(5) JavaSE版——函数重载
1.函数 函数就是定义在类中具有特定功能的一段独立小程序,也称为方法. 定义函数的格式: 修饰符 返回值类型 函数名(参数类型 形式参数1,参数类型 形式参数2,...) { ...
- Redis应用场景[分享]
Redis应用场景[分享] 1.取最新N个数据的操作2.排行榜应用 取TOPN操作3.需要精确设定过期时间的应用4.计数器应用(文章阅读数.评论数)5.Uniq操作,获取某段时间所有数据排重值6.实时 ...
- Spring Boot 与ElasticSearch
一.ElasticSearch 介绍 开源的 ElasticSearch 是目前全文搜索引擎的首选,它是一个分布式搜索服务,提供Restful API,它可以快速地存储.搜索和分析海量数据.底层基 ...
- dorado 7 使用总结
最近项目上需要,使用了dorado 7 ,总体感觉还可以,快速开发很方便,然而在方便的同时,难免有些太过繁琐,很多东西都封装了起来,会造成很多不便.因此快速开发的项目可以使用,其它的不推荐.现在打算将 ...
- QT使用插件QAxWidget来展示web页面
要求:用qt版开发一个桌面程序,该程序有一个界面,用来显示一个采用silverlight开发的web页面. 分析:在qt中实现web显示,根据qt的版本和对应编译器的版本,有如下选择: (1)5.6以 ...
- 洛谷——P2827 蚯蚓
P2827 蚯蚓 题目描述 本题中,我们将用符号 \lfloor c \rfloor⌊c⌋ 表示对 cc 向下取整,例如:\lfloor 3.0 \rfloor = \lfloor 3.1 \rflo ...