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.编译阶段,首先编译成纯汇编语句, ...
随机推荐
- Server in ASP.NET-Core
.NET-Core Series Server in ASP.NET-Core DI in ASP.NET-Core Routing in ASP.NET-Core Error Handling in ...
- Download the Hibernate Tools
首先去官网上下载最新版本的Hibernate Tools JBoss Tools 4.5.0.Final Requirements: Java 8 and Eclipse Oxygen 4.7 有 4 ...
- Linux 更改ssh 端口
部署了一个测试服务器之后,在查看linux日志的时候,发现莫名的IP一直在访问服务器,感觉像是某种恶意扫描,来攻击服务器的.因此更改ssh端口. 输入: vim /etc/ssh/sshd_confi ...
- ACM学习之路___HDU 1385(带路径保存的 Floyd)
Description These are N cities in Spring country. Between each pair of cities there may be one trans ...
- Canvas+Video打造酷炫播放体验
一.简介 直到现在,仍然不存在一项旨在网页上显示视频的标准. 今天,大多数视频是通过插件(比如 Flash)来显示的.然而,并非所有浏览器都拥有同样的插件. HTML5 规定了一种通过 video 元 ...
- 第1回-使用ThinkPHP的3.1.3版本轻松建网站
使用ThinkPHP的3.1.3版本轻松建网站 首先,从ThinkPHP官网下载一个ThinkPHP3.1.3版本框架包. 其次,取出ThinkPHP3.1.3包中的核心部分,部署你的服务器项目下. ...
- 一次生产环境下MongoDB备份还原数据
最近开发一个版本的功能当中用到了MongoDB分页,懒于造数据,于是就研究了下从生产环境上导出数据到本地来进行测试. 研究了一下,发现MongoDB的备份还原和MySQL语法还挺类似,下面请看详细介绍 ...
- PHP抓取网页图片
<?php set_time_limit(0);//抓取不受时间限制 if($_POST['Submit']=="开始抓取"){ $URL=$_POST['link']; g ...
- svn服务端安装、权限修改以及客户端的使用
2017-10-1016:10:2 svn服务端安装.权限修改以及客户端的使用 svn服务端.客户端.汉化包下载 http://pan.baidu.com/s/1c1Ogj2C 1.安装服务器端程序( ...
- 电脑IP地址被占用如何释放?
回车后,关机,等待5分钟左右再开机,就释放掉了.