上一篇  详解go语言的array和slice 【一】已经讲解过,array和slice的一些基本用法,使用array和slice时需要注意的地方,特别是slice需要注意的地方比较多。上一篇的最后讲解到创建新的slice时使用第三个索引来限制slice的容量,在操作新slice时,如果新slice的容量大于长度时,添加新元素依然后使源的相应元素改变。这一篇里我会讲解到如何避免这些问题,以及迭代、和做为方法参数方面的知识点。

slice的长度和容量设置为同一个值

  如果在创建新的slice时我们把他的长度和容量的值设置为样的值,那么在append新元素时,底层会创建一个新的array并把之前的值复制过去。这样就不会影响之前共同的底层array了。

    // 创建一个容量和长度均为6的sliceslice1 := []int{5, 23, 10, 2, 61, 33}// 对slices1进行切片,长度为2容量为3slice2 := slice1[1:3:3]fmt.Println("cap", cap(slice2))fmt.Println("slice2", slice2)//修改一个共同指向的元素//两个slice的值都会修改slice2[0] = 11111fmt.Println("slice1", slice1)fmt.Println("slice2", slice2)// 增加一个元素slice2 = append(slice2, 55555)fmt.Println("slice1: ", slice1)fmt.Println("slice2: ", slice2)

  输出结果

cap 2
slice2 [23 10]
slice1 [5 11111 10 2 61 33]
slice2 [11111 10]
slice1:  [5 11111 10 2 61 33]
slice2:  [11111 10 55555]

  代码中的长度和容量是一样的,长度和容量的计算公式看我的上一篇博客。增加一个元素后,原来共同指向的底层数据是没有变的。因为slice2的底层array被重新赋值了。

迭代slice

  go语言内置一个关键字range用于迭代集合,当然他也可以迭代slice,也可以使用  _  来忽略我们不关心的元素,但是如果只关心index则不需这么写 for index,_ := range slice1。下在给出完整代码

    // 创建一个容量和长度均为6的sliceslice1 := []int{5, 23, 10, 2, 61, 33}for index, value := range slice1 {fmt.Println("index: ", index, " value: ", value)}// 可以忽略我们不关心的元素// 只关心valuefor _, value := range slice1 {fmt.Println("value ", value)}// 只关心index, 可以不用 _for index := range slice1 {fmt.Println("index: ", index)}

  需要注意的是rang 迭代的value值并是一个复本,我们可以对比一下迭代的value和原slice内相应index下value的地址:

    // 创建一个容量和长度均为6的sliceslice1 := []int{5, 23, 10, 2, 61, 33}for index, value := range slice1 {fmt.Println("index: ", index, " value address : ", &value, " slice1 value address", &slice1[index])}

  输出结果

index:  0  value address :  0xc04204e088  slice1 value address 0xc04206a030
index:  1  value address :  0xc04204e088  slice1 value address 0xc04206a038
index:  2  value address :  0xc04204e088  slice1 value address 0xc04206a040
index:  3  value address :  0xc04204e088  slice1 value address 0xc04206a048
index:  4  value address :  0xc04204e088  slice1 value address 0xc04206a050
index:  5  value address :  0xc04204e088  slice1 value address 0xc04206a058

  slice1中value的地址是不断变化的。而迭代的value值的地址没有变化,这是因为value是一个变量,为次迭代的时候赋不同的值。我们把代码写成下面这样,你就清楚了

    var index, value intfor index, value = range slice1 {fmt.Println("index: ", index, &index, " value address : ", &value, " slice1 value address", &slice1[index])}

  除了使用rang 也可以使用传统的for循环来做迭代

    slice1 := []int{5, 23, 10, 2, 61, 33}for i, len := 1, len(slice1); i < len; i++ {fmt.Println("index: ", i, " value:", slice1[i])}

slice作为方法参数

  由于slice的特殊结构,有一个指针指向一个数组

    s := make([]int, 2, 5)fmt.Println("len: ", len(s))fmt.Println("cap: ", cap(s))s = append(s, 2)s[0] = 12

  所以,slice做为方法的参数传递时,只会复制slice本身而不会复制slice底层的array.如果我们创建一个int类型有100万长度的slice ,把他传递给一个方法时,只需要复制24个字节就够了。指针需要8个,长度和容量都是8个。

const size int = 1000 * 1000func main() {slice0 := make([]int, size)fmt.Println("slice0 len: ", len(slice0), " cap :", cap(slice0))doSomeThing(slice0)
}func doSomeThing(s []int) {fmt.Println(len(s))
}

转载于:https://www.cnblogs.com/li-peng/p/7541554.html

详解go语言的array和slice 【二】相关推荐

  1. 详解go语言的array和slice 【一】

    本篇会详细讲解go语言中的array和slice,和平时开发中使用时需要注意的地方,以免入坑. Go语言中array是一组定长的同类型数据集合,并且是连续分配内存空间的. 声明一个数组 var arr ...

  2. c语言malloc用法 数组,详解C语言用malloc函数申请二维动态数组的实例

    详解C语言用malloc函数申请二维动态数组的实例 C语言在程序运行中动态的申请及释放内存十分方便,一维数组的申请及释放比较简单. Sample one #include int main() { c ...

  3. DBus glib 各数据类型接收与发送详解—C语言(3)

    DBus glib 各数据类型接收与发送详解-C语言(3) 动机 前置知识 正文 Python 测试服务 使用 C 实现复杂数据类型的传递 DICT_DICT ObjectPath_Dict_Stru ...

  4. php 微信 公众 平台,微信公众平台代码详解-php语言(一)

    2.这里把它粘贴出来,以注释的形式进行讲解. 3.首先我们要知道一些基础的知识: (1)要有自己的网站--公网环境,其中一个php页面处理微信消息: (2)微信公众平台和网站服务器之间是通过XML数据 ...

  5. #转载:杨辉三角形实现过程详解-c语言基础

    杨辉三角形实现过程详解-C语言基础 十一一个人 2018-12-26 06:45:45 6465 收藏 28 最后发布:2018-12-26 06:45:45首发:2018-12-26 06:45:4 ...

  6. 武林c语言,详解C语言中条件编译

    预处理器提供条件编译,程序的不同部分可以在不同的条件下编译,从而产生不同的目标代码文件,这对于程序移植和调试非常有用,本文是武林技术频道小编给为大家带来的详解中条件编译,一起来了解一下吧! 通常情况, ...

  7. php怎么求最小公倍数,C++_详解C语言求两个数的最大公约数及最小公倍数的方法,求两个正整数的最大公约数nbs - phpStudy...

    详解C语言求两个数的最大公约数及最小公倍数的方法 求两个正整数的最大公约数 思路:这是一个很基本的问题,最常见的就是两种方法,辗转相除法和辗转相减法.通式分别为 f(x, y) = f(y, x%y) ...

  8. 你是真的“C”——详解C语言函数模块知识(上篇)

    详解C语言函数模块知识(上篇)

  9. 详解c语言main函数、printf函数、scanf函数与va家族

    C语言入门与提升(1)--详解c语言main函数.printf函数与scanf函数,与va家族 前言: 为什么要学习C语言呢?C语言作为最古老的语言之一,走过了半个多世纪的风风雨雨,至今仍然长盛不衰, ...

最新文章

  1. 为所有PHP-FPM容器构建单独的NGinx Dock镜像
  2. c语言奇数值结点链表,习题11-7 奇数值结点链表 (20 分)
  3. OS / Linux / 文件描述符以及 file 结构体
  4. java jxl之Excel的读取
  5. 计算机管理用户和组无法访问,同一工作组无法访问如何解决【详解】
  6. 关键字驱动测试示例_带有示例的False关键字
  7. Graph Embedding:word2vec更进一步?
  8. 重构:改善既有代码的设计 精彩书评二
  9. 【水果识别】基于matlab GUI柑橘质量检测及分级系统【含Matlab源码 738期】
  10. 【2017CCPC哈尔滨赛区 HDU 6242】Geometry Problem【随机化】
  11. Python利用情感词典做情感分析
  12. STM32和51系列单片机编程的区别
  13. 耗时162天,从华为外包5k转岗正式员工15k,经历的心酸只有自己知道
  14. copy 复制文件夹目录下所有文件,包括子目录 (新思路)
  15. UVC app流程图
  16. 悉尼大学计算机录取要求,悉尼大学录取要求
  17. 2018-10-20-WPF-通过位处理合并图片
  18. sql 内连接,左连接,右连接,全连接
  19. 公众号分享页面php,微信公众号网页分享功能开发的示例代码
  20. 考研英语二81分复习经验分享|资料推荐|复习方法|复习规划

热门文章

  1. opencv在python环境下的安装_python环境下安装opencv库的方法
  2. scrapy如何指定生成python3的项目_如何把阿里图标库的图标生成代码并应用于自己的项目...
  3. linux top 命令可视化_Linux top命令使用详解:显示或管理执行中的程序
  4. 华南农业大学计算机专业学硕20,2020年华南农业大学计算机应用技术考研经验分享...
  5. Collections.min()和Collections.max()的使用
  6. 面试题-- 什么是偏向锁
  7. RocketMQ集成SpringBoot
  8. mysql漏洞包_MySQL npm包中的本地文件泄露漏洞
  9. jmeter存储http请求返回参数_Jmeter接口测试之HTTP请求默认值(八)
  10. 收集21个经典Java面试题