详解go语言的array和slice 【二】
上一篇 详解go语言的array和slice 【一】已经讲解过,array和slice的一些基本用法,使用array和slice时需要注意的地方,特别是slice需要注意的地方比较多。上一篇的最后讲解到创建新的slice时使用第三个索引来限制slice的容量,在操作新slice时,如果新slice的容量大于长度时,添加新元素依然后使源的相应元素改变。这一篇里我会讲解到如何避免这些问题,以及迭代、和做为方法参数方面的知识点。
slice的长度和容量设置为同一个值
如果在创建新的slice时我们把他的长度和容量的值设置为样的值,那么在append新元素时,底层会创建一个新的array并把之前的值复制过去。这样就不会影响之前共同的底层array了。
// 创建一个容量和长度均为6的slice
slice1 := []int{, , , , , }
// 对slices1进行切片,长度为2容量为3
slice2 := slice1[::]
fmt.Println("cap", cap(slice2))
fmt.Println("slice2", slice2) //修改一个共同指向的元素
//两个slice的值都会修改
slice2[] =
fmt.Println("slice1", slice1)
fmt.Println("slice2", slice2) // 增加一个元素
slice2 = append(slice2, ) fmt.Println("slice1: ", slice1)
fmt.Println("slice2: ", slice2)
输出结果
cap
slice2 [ ]
slice1 [ ]
slice2 [ ]
slice1: [ ]
slice2: [ ]
代码中的长度和容量是一样的,长度和容量的计算公式看我的上一篇博客。增加一个元素后,原来共同指向的底层数据是没有变的。因为slice2的底层array被重新赋值了。
迭代slice
go语言内置一个关键字range用于迭代集合,当然他也可以迭代slice,也可以使用 _ 来忽略我们不关心的元素,但是如果只关心index则不需这么写 for index,_ := range slice1。下在给出完整代码
// 创建一个容量和长度均为6的slice
slice1 := []int{, , , , , } for index, value := range slice1 {
fmt.Println("index: ", index, " value: ", value)
} // 可以忽略我们不关心的元素
// 只关心value
for _, value := range slice1 {
fmt.Println("value ", value)
} // 只关心index, 可以不用 _
for index := range slice1 {
fmt.Println("index: ", index)
}
需要注意的是range 迭代的value值并不是一个复本,我们可以对比一下迭代的value和原slice内相应index下value的地址:
// 创建一个容量和长度均为6的slice
slice1 := []int{, , , , , } for index, value := range slice1 {
fmt.Println("index: ", index, " value address : ", &value, " slice1 value address", &slice1[index]) }
输出结果
index: value address : 0xc04204e088 slice1 value address 0xc04206a030
index: value address : 0xc04204e088 slice1 value address 0xc04206a038
index: value address : 0xc04204e088 slice1 value address 0xc04206a040
index: value address : 0xc04204e088 slice1 value address 0xc04206a048
index: value address : 0xc04204e088 slice1 value address 0xc04206a050
index: value address : 0xc04204e088 slice1 value address 0xc04206a058
slice1中value的地址是不断变化的。而迭代的value值的地址没有变化,这是因为value是一个变量,每次迭代的时候赋不同的值。我们把代码写成下面这样,你就清楚了
var index, value int
for index, value = range slice1 {
fmt.Println("index: ", index, &index, " value address : ", &value, " slice1 value address", &slice1[index]) }
除了使用range 也可以使用传统的for循环来做迭代
slice1 := []int{, , , , , } for i, len := , len(slice1); i < len; i++ {
fmt.Println("index: ", i, " value:", slice1[i])
}
slice作为方法参数
由于slice的特殊结构,有一个指针指向一个数组
s := make([]int, , )
fmt.Println("len: ", len(s))
fmt.Println("cap: ", cap(s))
s = append(s, ) s[] =
所以,slice做为方法的参数传递时,只会复制slice本身而不会复制slice底层的array.如果我们创建一个int类型有100万长度的slice ,把他传递给一个方法时,只需要复制24个字节就够了。指针需要8个,长度和容量都是8个。
const size int = * func main() {
slice0 := make([]int, size)
fmt.Println("slice0 len: ", len(slice0), " cap :", cap(slice0))
doSomeThing(slice0)
} func doSomeThing(s []int) {
fmt.Println(len(s))
}
详解go语言的array和slice 【二】的更多相关文章
- 详解go语言的array和slice 【一】
本篇会详细讲解go语言中的array和slice,和平时开发中使用他样时需要注意的地方,以免入坑. Go语言中array是一组定长的同类型数据集合,并且是连续分配内存空间的. 声明一个数组 var a ...
- 详解 Go 语言中的 time.Duration 类型
swardsman详解 Go 语言中的 time.Duration 类型swardsman · 2018-03-17 23:10:54 · 5448 次点击 · 预计阅读时间 5 分钟 · 31分钟之 ...
- 详解Go语言调度循环源码实现
转载请声明出处哦~,本篇文章发布于luozhiyun的博客: https://www.luozhiyun.com/archives/448 本文使用的go的源码15.7 概述 提到"调度&q ...
- 【详解】ThreadPoolExecutor源码阅读(二)
系列目录 [详解]ThreadPoolExecutor源码阅读(一) [详解]ThreadPoolExecutor源码阅读(二) [详解]ThreadPoolExecutor源码阅读(三) AQS在W ...
- 详解Javascript中的Array对象
基础介绍 创建数组 和Object对象一样,创建Array也有2种方式:构造函数.字面量法. 构造函数创建 使用构造函数的方式可以通过new关键字来声明,如下所示: 12 var arr = new ...
- Rserve详解,R语言客户端RSclient【转】
R语言服务器程序 Rserve详解 http://blog.fens.me/r-rserve-server/ Rserve的R语言客户端RSclient https://blog.csdn.net/u ...
- Linux进程上下文切换过程context_switch详解--Linux进程的管理与调度(二十一)
1 前景回顾 1.1 Linux的调度器组成 2个调度器 可以用两种方法来激活调度 一种是直接的, 比如进程打算睡眠或出于其他原因放弃CPU 另一种是通过周期性的机制, 以固定的频率运行, 不时的检测 ...
- LeetCode刷题 1. Two Sum 两数之和 详解 C++语言实现 java语言实现
1. Two Sum 两数之和 Given an array of integers, return indices of the two numbers such that they add up ...
- 机器学习|线性回归算法详解 (Python 语言描述)
原文地址 ? 传送门 线性回归 线性回归是一种较为简单,但十分重要的机器学习方法.掌握线性的原理及求解方法,是深入了解线性回归的基本要求.除此之外,线性回归也是监督学习回归部分的基石. 线性回归介绍 ...
随机推荐
- LinkedList之modCount和expectedModCount
modCount和expectedModCount是用于表示修改次数的,其中modCount表示集合的修改次数,这其中包括了调用集合本身的add方法等修改方法时进行的修改和调用集合迭代器的修改方法进行 ...
- css知识点
css知识点 一.盒模型知识 border: 边框 border-width:边框的宽度 border-color:边框的颜色 border-style:边框的线型 border-top:上边框 bo ...
- RSA简介(四)——求逆算法
此处所谓求逆运算,是指在模乘群里求逆. 第一节里提到互质的两个定义: (1)p,q两整数互质指p,q的最大公约数为1. (2)p.q两整数互质指存在整数a,b,使得ap+bq=1. 只要明白了欧几里得 ...
- cygwin环境c语言开发
. 在windows上开发c语言,使用sublime编辑器 在工具栏tools-->run 结果报错,原因是没有在GNU环境下使用sublime text2 在 cygwin环境下启动subli ...
- 缓存一致性和跨服务器查询的数据异构解决方案canal
当你的项目数据量上去了之后,通常会遇到两种情况,第一种情况应是最大可能的使用cache来对抗上层的高并发,第二种情况同样也是需要使用分库 分表对抗上层的高并发...逼逼逼起来容易,做起来并不那么乐观, ...
- 移动端touch事件 || 上拉加载更多
前言: 说多了都是泪,在进行项目开发时,在上拉加载更多实现分页效果的问题上,由于当时开发任务紧急,所以就百度找了各种移动端的上拉下拉 实现加载更多的插件.然后就留下了个坑:上拉加载的时候会由于用户错误 ...
- python_控制台输出带颜色的文字方法
在开发项目过程中,为了方便调试代码,经常会向stdout中输出一些日志,默认的这些日志就直接显示在了终端中.而一般的应用服务器,第三方库,甚至服务器的一些通告也会在终端中显示,这样就搅乱了我们想要的信 ...
- MongoDB分布式集群搭建(分片加副本集)
# 环境准备 服务器 # 环境搭建 文件配置和目录添加 新建目录的操作要在三台机器中进行,为配置服务器新建数据目录和日志目录 mkdir -p $MONGODB_HOME/config/data mk ...
- Java基础---继承、抽象、接口
一.概述 继承是面向对象的一个重要特征.当多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继那个类即可.这时,多个类可以称为子类,单 ...
- jmeter系列-------脚本调试
1.调试的时候 可以只跑需要调试的接口,禁用其他的接口 2.每个接口都需要增加断言眼,保证脚本的结果的正确性 3.验证脚本的可靠性,可以切换用户(测试变量)来进行调试 4.使用Debug Sample ...