Golang基础(一)-- slice用法和本质

魔改谢馒头 · · 997 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

今天问题问的很基础,考察了很多概念性问题,有些没有答上来,自己做一下笔记

Q1:Golang里哪些是值类型,哪些是引用类型

A1:Golang中只有三种引用类型:slice(切片)、map(字典)、channel(管道);

关联知识:slice用法和本质:

转自:https://studygolang.com/articles/5877
数组
Go的切片是在数组之上的抽象数据类型,因此在了解切片之前必须要要理解数组。
数组类型由指定和长度和元素类型定义。例如,
[4]int 类型表示一个四个整数的序列。数组的长度是固定的,长度是数组类型的一部分(int[4] 和 [5]int 是完全不同的类型)。
数组可以以常规的索引方式访问,表达式 s[n] 访问数组的第n 个元素。
数组不需要显式的初始化;数组元素会自动初始化为零值:

切片

数组虽然有适用它们的地方,但是数组不够灵活,因此在Go代码中数组使用的并不多。但是,切片则使用得相当广泛。切片基于数组构建,但是提供更强的功能和便利。
切片的类型是 []T,T 是切片元素的类型。和数组不同的是,切片没有固定的长度。

切片的本质

一个切片是一个数组切割区间的描述。它包含了指向数组的指针,切割区间的长度,和容量(切割区间的最大长度)。

可能的“陷阱”

正如前面所说,切片操作并不会复制底层的数组。此层的数组将被保存在内存中,知道它不再被引用。有时候可能会因为一个小的内存引用导致保存所有的数据。

例如,FindDigits 函数加载整个文件到内存,然后搜索第一个连续的数字,最后结果以切片方式返回。

var digitRegexp = regexp.MustCompile("[0-9]+")

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

这段代码的行为和广告类似,返回的 []byte 指向保存整个文件的数组。因为切片引用了原始的数组,导致GC不能释放数组的空间;一个小的需求导致需要保存整个文件。
(切片引用了原始数组,切片操作不会影响到底层数组,返回以后导致GC不能释放数组空间。所以修复这个问题需要将切片拷贝到一个新的切片中,旧数组在方法返回时就会释放)
要修复整个问题,可以将感兴趣的数据复制到一个新的切片中:

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

有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:魔改谢馒头

查看原文:Golang基础(一)-- slice用法和本质

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

997 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传