今天问题问的很基础,考察了很多概念性问题,有些没有答上来,自己做一下笔记
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
}
有疑问加站长微信联系(非本文作者)