切片

切片(slice)是对数组一个连续片段的引用(该数组我们称之为相关数组,通常是匿名的),所以切片是一个引用类型(因此更类似于 C/C++ 中的数组类型,或者 Python 中的 list 类型)

切片是一个 长度可变的数组。

多个切片如果表示同一个数组的片段,它们可以共享数据;因此一个切片和相关数组的其他切片是共享存储的,相反,不同的数组总是代表不同的存储。数组实际上是切片的构建块。

优点 因为切片是引用,所以它们不需要使用额外的内存并且比使用数组更有效率,所以在 Go 代码中 切片比数组更常用。

声明切片的格式是: var identifier []type(不需要说明长度)。

一个切片在未初始化之前默认为 nil,长度为 0。

切片也可以用类似数组的方式初始化:var x = []int{2, 3, 5, 7, 11}。这样就创建了一个长度为 5 的数组并且创建了一个相关切片。

切片在内存中的组织方式实际上是一个有 3 个域的结构体:指向相关数组的指针,切片 长度以及切片容量。下图给出了一个长度为 2,容量为 4 的切片。——注意看其中的内存共享方式!!!

  • y[0] = 3 且 y[1] = 5
  • 切片 y[0:4] 由 元素 3, 5, 7 和 11 组成。

注意 绝对不要用指针指向 slice。切片本身已经是一个引用类型,所以它本身就是一个指针!!

7.2.2 将切片传递给函数

如果你有一个函数需要对数组做操作,你可能总是需要把参数声明为切片。当你调用该函数时,把数组分片,创建为一个 切片引用并传递给该函数。这里有一个计算数组元素和的方法:

func sum(a []int) int {s := 0 for i := 0; i < len(a); i++ { s += a[i] } return s } func main() { var arr = [5]int{0, 1, 2, 3, 4} sum(arr[:]) }

7.2.3 用 make() 创建一个切片

当相关数组还没有定义时,我们可以使用 make() 函数来创建一个切片 同时创建好相关数组:var slice1 []type = make([]type, len)

下图描述了使用 make 方法生成的切片的内存结构:

7.2.4 new() 和 make() 的区别

看起来二者没有什么区别,都在堆上分配内存,但是它们的行为不同,适用于不同的类型。

  • new(T) 为每个新的类型T分配一片内存,初始化为 0 并且返回类型为*T的内存地址:这种方法 返回一个指向类型为 T,值为 0 的地址的指针,它适用于值类型如数组和结构体(参见第 10 章);它相当于 &T{}
  • make(T) 返回一个类型为 T 的初始值,它只适用于3种内建的引用类型:切片、map 和 channel(参见第 8 章,第 13 章)。

换言之,new 函数分配内存,make 函数初始化;下图给出了区别:

在图 7.3 的第一幅图中:

var p *[]int = new([]int) // *p == nil; with len and cap 0 p := new([]int)

在第二幅图中, p := make([]int, 0) ,切片 已经被初始化,但是指向一个空的数组。

以上两种方式实用性都不高。下面的方法:

var v []int = make([]int, 10, 50)

或者

v := make([]int, 10, 50)

这样分配一个有 50 个 int 值的数组,并且创建了一个长度为 10,容量为 50 的 切片 v,该 切片 指向数组的前 10 个元素。

转自:https://github.com/Unknwon/the-way-to-go_ZH_CN/blob/master/eBook/07.2.md

7.6.3 字符串和切片的内存结构

字符串 string s = "hello" 和子字符串 t = s[2:3] 在内存中的结构可以用下图表示:

7.6.8 切片和垃圾回收

切片的底层指向一个数组,该数组的实际容量可能要大于切片所定义的容量。只有在没有任何切片指向的时候,底层的数组内层才会被释放,这种特性有时会导致程序占用多余的内存。

示例 函数 FindDigits 将一个文件加载到内存,然后搜索其中所有的数字并返回一个切片。

var digitRegexp = regexp.MustCompile("[0-9]+") func FindDigits(filename string) []byte { b, _ := ioutil.ReadFile(filename) return digitRegexp.Find(b) }

这段代码可以顺利运行,但返回的 []byte 指向的底层是整个文件的数据。只要该返回的切片不被释放,垃圾回收器就不能释放整个文件所占用的内存。换句话说,一点点有用的数据却占用了整个文件的内存。

想要避免这个问题,可以通过拷贝我们需要的部分到一个新的切片中:

func FindDigits(filename string) []byte {b, _ := ioutil.ReadFile(filename) b = digitRegexp.Find(b) c := make([]byte, len(b)) copy(c, b) return c }

转载于:https://www.cnblogs.com/bonelee/p/6862377.html

go语言笔记——切片底层本质是共享数组内存!!!绝对不要用指针指向 slice切片本身已经是一个引用类型就是指针...相关推荐

  1. go语言笔记——append底层实现和Cpp vector无异,只是有返回值,double后返回了新的vector地址而已...

    切片的复制与追加 如果想增加切片的容量,我们必须创建一个新的更大的切片并把原分片的内容都拷贝过来.下面的代码描述了从拷贝切片的 copy 函数和向切片追加新元素的 append 函数. 示例 7.12 ...

  2. C语言笔记 第三十五课 数组参数和指针参数分析

    第三十五课 数组参数和指针参数分析 思考:为什么C语言中的数组参数会退化为指针? 退化的意义 C语言中只会以值拷贝的方式传输参数 当向函数传递数组时:(错误的,设计当初的思路) 将整个数组拷贝一份传入 ...

  3. go语言笔记——多值函数,本质上和nodejs的回调很像,不过nodejs是回调的第一个参数是err,而golang里是第二个!...

    5.2 测试多返回值函数的错误 Go 语言的函数经常使用两个返回值来表示执行是否成功:返回某个值以及 true 表示成功:返回零值(或 nil)和 false 表示失败(第 4.4 节).当不使用 t ...

  4. cout 数组_C语言学习笔记(十)二维数组内存预设

    1 问题描述 二维数组存储数据数量根据其他方法间接获得: 为当前数据数量申请内存: 2 相关程序 #include --2020.11.23--

  5. OC语言笔记(三):OC数组和字典

    提示: C和OC的差别 1.C的数组,只能存一种类型,OC的数组,可以同时保存不同类型的对象 2.C的数组,一般保存基本数据类型,OC的数组,只能保存对象 OC的数组 一.NSArray 1.实例化 ...

  6. C语言笔记-10-函数空间-函数概念与规则

    C语言笔记-10-函数空间-概念与规则 文章目录 C语言笔记-10-函数空间-概念与规则 前言 一.函数概念 1.传入参数 2.返回值 二.函数参数 三.指针函数-函数名指针化 1.指针指向其他函数的 ...

  7. go slice切片详解:定义、遍历、追加切片、切片拷贝

    引入 [1]切片(slice)是golang中一种特有的数据类型 [2]数组有特定的用处,但是却有一些呆板(数组长度固定不可变),所以在 Go 语言的代码里并不是特别常见.相对的切片却是随处可见的,切 ...

  8. c语言指针指向数组首地址,C语言指向数组元素的指针

    指向数组元素的指针和运算法则 所谓指向数组元素的指针,其本质还是变量的指针.因为数组中的每个元素,其实都可以直接看成是一个变量,所以指向数组元素的指针,也就是变量的指针. 指向数组元素的指针不难,但很 ...

  9. C语言课程训练系统题-二维数组cqupt

    C语言课程训练系统题-二维数组cqupt 1.杨辉三角 2.输出每列最小值 3.一个n位正整数如果等于它的n个数字的n次方和,该数称为n位自方幂数.设计求3~6位自方幂数 4.有如下3*4的矩阵,求出 ...

最新文章

  1. php时间相减_请教一个PHP的时间戳转换成时间相减的問題?
  2. 尊重个体多样性,科学人文终统一
  3. c语言偏移一个字节,文件偏移量与C语言中的流定位
  4. 如何在Outlook 2013中管理附件
  5. 关于runc漏洞CVE-2019-5736的修复公告
  6. TestCase / test plan / test case
  7. 自学python如何就业_python学习:想要自学Python达到就业的水平,应该怎么去学习...
  8. java day22【网络编程】
  9. 《云网络:数字经济的连接》图书发布会将于7月16日在杭举行
  10. 2018天梯赛第一次训练题解和ac代码
  11. 天下所有的事,都是为了利益,都是按利益逻辑规律在运行,发生的一切事情都可以用利益逻辑来解释
  12. 计算机软硬件基本知识总结,计算机软硬件基础知识.doc
  13. 谈我们的团队文化建设
  14. elasticsearch 数据类型
  15. 关于项目中数据库密码加密的使用
  16. Vue-纯前端导出word文档 Can‘t find end of central directory:is this a zip file?
  17. APM32F103 RTC内部时钟源报警中断例程测试
  18. 用IP地址签发SSL证书
  19. 统一网关 Gateway
  20. TTS(TextToSpeach)语音朗读实例

热门文章

  1. 河池学院计算机与信息工程学院官网 领导,关于成立我院宣传工作领导小组的方案...
  2. 网站做好后不能用手机浏览吗_企业几年前制作的网站大部分都应该被淘汰掉
  3. date转换成string hive_[转] String to Date conversion in hive - 在 Hive 中各种字符串转换成日期格式...
  4. php intval 变小,php intval() 小数时安全漏洞分析
  5. java和c++的区别大吗_安徽成人高考和自考区别大吗?为什么推荐选成人高考?
  6. android编译.a文件,Android 7.1源码编译导入AS完整教程
  7. 关于php的cgi,php-fpm的关系
  8. git 如何正确的提交文件
  9. python【OS操作系统库】Python的os模块大宝剑(全)
  10. python【蓝桥杯vip练习题库】ADV-172身份证排序