《The anatomy of Slices in Go》学习笔记
《The anatomy of Functions in Go》学习笔记
切片与数组
切片 VS 数组的定义
- 切片是一个用来存储相同类型元素的容器,切片的长度不是固定的
- 数组是一个用来存储相同类型元素的容器,数组的长度是固定的
切片与数组的表示
切片
var s []int
数组
var s [5]int
切片与数组的zero值
- 切片的zero值是nil
- 数组的zero值是元素类型的默认值,如 var s [5]int 的默认值是[0,0,0,0,0]
数组与切片作为函数的参数值
- 数组作为函数的参数值传递仅仅是数组的拷贝
- 切片作为函数的参数值传递的是切片的引用
数组
初始化值
var a [n]T = [n]T{V1,V2,…,Vn}
_
var a [3]int = [3]int{1, 2, 3}
var a = [3]int{1, 2, 3}
a := [3]int{1, 2, 3}
多行初始化值
最后一个元素必须以逗号结束
var a = [3]string {
"WHO",
"AM",
"I",
}
自动声明数组的长度
var a = [...]string {
"WHO",
"AM",
"I",
}
计算数组的长度
len()
_
比较数组的异同
- 数组的长度必须相同
- 数组对应位置上的元素必须相同
遍历数组
package main
import "fmt"
func main() {
a := [...]int{1,3,5,7,9}
for index, value := range a {
fmt.Printf("a[%d] is %d\n", index, value)
}
}
切片
指定数组的元素作为切片的值
[:]
切片的长度和容量
_len() 和 cap()
_
- 切片是一种结构体
type slice struct {
zerothElement *type // 切片引用数组第一个元素的指针
len int // 切片的长度
cap int // 切片的容量
}
由于切片仅仅是数组的引用,因此对切片的修改将会导致数组的值被修改
**
向切片中添加元素以及复制切片
append 函数 (golang内置)
func append(slice []Type, elems …Type) []Type
- 如果将append函数的结果赋值给新的切片,原切片不会发生任何变化
- 若添加元素得到切片的length小于被添加切片的capacity,被添加切片对应数组的相应位置上元素将会发生变化
- 若添加元素得到切片的length大于被添加切片的capacity,被添加切片对应数组不会发生变化
以上两三点的主要区别在于当添加后切片的length大于capacity后,切片底层数组不能容下新添加的元素,因此会创建新的数组作为切片的底层数组。这样原切片对应的数组不会发生变化
copy 函数 (golang内置)
func copy(dst []Type, src []Type) int
注意:如果dst对应的切片是nil切片,copy函数不能生效
nil切片 VS 空切片
- nil切片指仅仅定义切片并没有引用任一数组
- 空切片指切片引用的数组为空
make函数 (golang内置)
s := make([]type, len, cap)
make函数用来创建指定类型的空切片
实战技巧
… 解构切片
package main
import "fmt"
func main() {
s1 := make([]int, 0, 10)
s2 := []int{1,3,5,7}
s1 = append(s1, s2...)
}
删除切片的元素
package main
import "fmt"
func main() {
s := []int{1,2,3,4,5,6,7,8,9}
s = append(s[:2], s[3:]...)
fmt.Printf("slice value is %v\n", s)
}
内存优化
切片引用的是数组,如果数组非常大,而且切片仅仅引用数组中小部分元素,因此只要切片在使用,对应的数组就不能得到释放,可以通过make函数创建空切片,并将数组中需要的元素通过切片copy到刚刚创建的切片上
**
package main
import "fmt"
func changeValue() []string {
arr := [10]string{
"ANHUI",
"ZHEJIANG",
"GUANGZHOU",
"CHONGQINF",
"DALIAN",
"NINGXIA",
"LIAONING",
"SHENZHEN",
"HUERHAOTE",
"KUNMING",
}
newSlice := make([]string, 3)
copy(newSlice, arr[:3])
return newSlice
}
func main() {
s := changeValue()
fmt.Printf("new slice value is %v\n", s)
}