Go语言中slice使用注意事项
- 指向底层数组的指针
- slice目前使用到的底层数组的元素个数,即长度
- 底层数组的最大长度,即容量
- 当从左边界有截断时,会改变新切片容量大小
- 左边界默认0,最小为0;右边界默认slice的长度,最大为slice的容量
- 当然,因为指向同一个底层数组,对新slice的操作会影响到原来的slice
a := []int{1, 2, 3, 4, 5}
b := a
func main() {
a := []int{1, 2, 3, 4, 5}
modifySlice(a)
//[10 2 3 4 5]
fmt.Println(a)
}
func modifySlice(s []int) {
s[0] = 10
}
func main() {
a := []int{1, 2, 3, 4, 5}
modifySlice(a)
//[1 2 3 4 5]
fmt.Println(a)
}
func modifySlice(s []int) {
s = []int{10, 20, 30, 40, 50}
}
示例代码 https://play.golang.org/p/LbFovzP-Rj
但是,如上所示,在调用函数的内部,将s整体赋值一个新的slice,并不会改变a的值,因为modifySlice函数内对s重新的整体赋值,让s指向了一个新的底层数组,而不是传递进来之前的a指向的那个数组,之后s的任何操作都不会影响到a了。
func main() {
a := make([]int, 2, 4)
//通常append操作都是将返回值赋值给自己,
//此处为了方便说明,没有这样做
b := append(a, 1)
//改变b的前2个元素值 会影响到a
b[0] = 99
//a: [99 0] &a[0]: 0x10410020 len: 2 cap: 4
fmt.Println("a:", a, " &a[0]:", &a[0], " len:", len(a), " cap:", cap(a))
//b: [99 0 1] &b[0]: 0x10410020 len: 3 cap: 4
fmt.Println("b:", b, " &b[0]:", &b[0], " len:", len(b), " cap:", cap(b))
}
func main() {
a := make([]int, 2, 4)
//通常append操作都是将返回值赋值给自己,
//此处为了方便说明,没有这样做
b := append(a, 1, 2, 3)
//改变b的前2个元素值 不会影响到a
b[0] = 99
//a: [0 0] &a[0]: 0x10410020 len: 2 cap: 4
fmt.Println("a:", a, " &a[0]:", &a[0], " len:", len(a), " cap:", cap(a))
//b: [99 0 1 2 3] &b[0]: 0x10454000 len: 5 cap: 8
fmt.Println("b:", b, " &b[0]:", &b[0], " len:", len(b), " cap:", cap(b))
}
func main() {
a := make([]int, 2, 4)
a[0] = 10
a[1] = 20
//a: [10 20] &a[0]: 0x10410020 len: 2 cap: 4
fmt.Println("a:", a, " &a[0]:", &a[0], " len:", len(a), " cap:", cap(a))
//进行append操作
b := append(a[:1], 1)
//a: [10 1] &a[0]: 0x10410020 len: 2 cap: 4
fmt.Println("a:", a, " &a[0]:", &a[0], " len:", len(a), " cap:", cap(a))
//b: [10 1] &b[0]: 0x10410020 len: 2 cap: 4
fmt.Println("b:", b, " &b[0]:", &b[0], " len:", len(b), " cap:", cap(b))
}
func main() {
a := make([]int, 2, 4)
a[0] = 10
a[1] = 20
//a: [10 20] &a[0]: 0x10410020 len: 2 cap: 4
fmt.Println("a:", a, " &a[0]:", &a[0], " len:", len(a), " cap:", cap(a))
//进行append操作
//append是在第一个元素后开始追加,所以要超过容量,至少要追加4个,而不是之前例子的3个
b := append(a[:1], 1, 2, 3, 4)
//a: [10 20] &a[0]: 0x10410020 len: 2 cap: 4
fmt.Println("a:", a, " &a[0]:", &a[0], " len:", len(a), " cap:", cap(a))
//b: [10 1 2 3 4] &b[0]: 0x10454020 len: 5 cap: 8
fmt.Println("b:", b, " &b[0]:", &b[0], " len:", len(b), " cap:", cap(b))
}
func main() {
a := make([]int, 2, 4)
a[0] = 10
a[1] = 20
//a: [10 20] &a[0]: 0x10410020 len: 2 cap: 4
fmt.Println("a:", a, " &a[0]:", &a[0], " len:", len(a), " cap:", cap(a))
testAppend(a[:1])
//a: [10 1] &a[0]: 0x10410020 len: 2 cap: 4
fmt.Println("a:", a, " &a[0]:", &a[0], " len:", len(a), " cap:", cap(a))
}
func testAppend(s []int) {
//进行append操作
s = append(s, 1)
//s: [10 1] &s[0]: 0x10410020 len: 2 cap: 4
fmt.Println("s:", s, " &s[0]:", &s[0], " len:", len(s), " cap:", cap(s))
}
Go语言中slice使用注意事项的更多相关文章
- Go语言中slice作为参数传递时遇到的一些“坑”
前言 相信看到这个题目,可能大家都觉得是一个老生常谈的月经topic了.一直以来其实把握一个"值传递"基本上就能理解各种情况了,不过最近遇到了更深一点的"小坑" ...
- Go语言中的slice
Go语言中的slice有点类似于Java中的ArrayList,但在使用上更加灵活,先通过下面一个小例子来体验一下如何通过一个已有的切片来产生一个新切片: func main() { slice := ...
- Delphi中获取Unix时间戳及注意事项(c语言中time()是按格林威治时间计算的,比北京时间多了8小时)
uses DateUtils;DateTimeToUnix(Now) 可以转换到unix时间,但是注意的是,它得到的时间比c语言中time()得到的时间大了8*60*60这是因为Now是当前时区的时间 ...
- [转]理解Go语言中的nil
最近在油管上面看了一个视频:Understanding nil,挺有意思,这篇文章就对视频做一个归纳总结,代码示例都是来自于视频. nil是什么 相信写过Golang的程序员对下面一段代码是非常非常熟 ...
- [转]Go语言中的make和new
前言 本文主要给大家介绍了Go语言中函数new与make的使用和区别,关于Go语言中new和make是内建的两个函数,主要用来创建分配类型内存.在我们定义生成变量的时候,可能会觉得有点迷惑,其实他们的 ...
- 在不同语言中static的用法
static (计算机高级语言) 编辑 像在VB,C#,C,C++,Java,PHP中我们可以看到static作为关键字和函数出现,在其他的高级计算机语言如FORTRAN.ALGOL.COBOL.BA ...
- ZH奶酪:C语言中malloc()和free()函数解析
1.malloc()和free()的基本介绍 (1)函数原型及说明 void *malloc(long NumBytes) 该函数分配了NumBytes个字节,并返回了指向这块内存的指针.如果分配失败 ...
- Go语言中new和make的区别
Go语言中new跟make是内置函数,主要用来创建分配类型内存. new( ) new(T)创建一个没有任何数据的类型为T的实例,并返回该实例的指针: 源码解析 func new func new(T ...
- C语言中,头文件和源文件的关系(转)
简单的说其实要理解C文件与头文件(即.h)有什么不同之处,首先需要弄明白编译器的工作过程,一般说来编译器会做以下几个过程: 1.预处理阶段 2.词法与语法分析阶段 3.编译阶段,首先编译成纯汇编语句, ...
随机推荐
- Spring - lookup-method方式实现依赖注入
引言 假设一个单例模式的bean A需要引用另外一个非单例模式的bean B,为了在我们每次引用的时候都能拿到最新的bean B,我们可以让bean A通过实现ApplicationContextWa ...
- 文件的inode号操作
linux给每个文件生成了一个唯一的inode编号,命令行下操作文件需要输入文件名,如果遇到文件名特别难输入(或者包含特殊符号)的情况,可以用inode号操作文件. 可以用这个命令查看inode号: ...
- 升级与修改Nginx
自从上次安装了Nginx后,学到了很多新的东西,比如http2.0... 而且还发现nginx还出了新版本,遂决定升级下,还是那个URL,下载最新版. ./configure --user=www - ...
- Mybatis——choose, when, otherwise可以达到switch case效果
在mapping文件中实现动态sql,如果想达到if else的效果可以使用:choose, when, otherwise <choose> <when test="ti ...
- [python学习笔记] String格式化
格式化 S % (args...) 方式 特点 str里的占位符同java里的占位符. 优势 这种方式可以限定格式化的时候接受的数据类型. 常见占位符 %d 接收数字,格式化为 十进制 %x 接收数字 ...
- Data_Struct(LinkList)
最近在学数据结构,学到链表这节作业有链表,毕竟菜鸟代码基本照看书上算法写的,再加上自己的小修改,这里先记录下来,万一哪天想看了,来看看. 里面有用到二级指针,还是不太理解,还有就是注释不多,后续有了更 ...
- NSTimer、CADisplayLink 内存泄漏
NSTimer.CADisplayLink 内存泄漏 内存泄漏的原因 CADisplayLink 要用 Taget 和 Selector 初始化,NSTimer 也可以用类似的方法初始化.这样初始化之 ...
- PuTsangTo
一. 跳跃与移动的优化与完善 先给上一次的内容做一次补救,也就是上一次中还留存的,由于键盘按键事件的第一次回调与后续回调之间会间隔个小半秒带来的跳跃落地后动作延迟的情况. 最终的键盘按下回调的处理代码 ...
- 【京东账户】——Mysql/PHP/Ajax爬坑之用户登录
一.引言 实现京东的账户项目,功能模块之一,用户登录.要用到的是Apach环境,Mysql.PHP以及Ajax. 二.依据功能创建库.表.记录 创建库:jd 创建表:登录表 添加三条记录 CREATE ...
- JS设计模式(二) 惰性模式
惰性模式:减少代码每次执行时的重复性判断,通过重新定义对象来避免原对象中的分支判断,提高网站性能. 例如针对不同浏览器的事件注册方法: var AddEvent = function(dom, typ ...