在实际开发中,大多数状况处理的数据都不是单一的,而是复数的同类型数据。全部的高级语言都会封装相应的数据结构、API等。在Go语言中,提供了数组、切片以及映射三种数据结构供开发者管理和处理集合数据。切片基于数组,却有别于数组,本次笔记学习Go切片相关的内容。数组
为了更方便学习切片的内容,首先简单了解一下切片的底层长什么样。 安全
使用内置数据结构的第一步:声明建立初始化。 切片有三种建立方式 使用make建立切片数据结构
//语法: make([]切片类型, 长度, 容量) 其中容量为可选值,容量>=长度
//建立一个长度为5,容量为10的整形切片
intSlice := make([]int, 5, 10)
//若是不指定容量值,则生成长度与容量相等的切片
//建立一个长度为10,容量为10的字符串切片
stringSlice := make([]string, 10)
复制代码
PS: make函数也可用于建立map及channel,如有写到相关内容再细聊。app
访问与修改切片元素与数组一致函数
intSlice[2] = 3
stringSlice[4] = "ji ni tai mei"
//未赋值的元素为默认零值
/* 若是访问的索引超过切片长度,编译会产生 index out of range越界异常,如 fmt.Println(intSlice[5]) */
复制代码
声明并初始化学习
//语法: []类型{初始化元素列表, ...}
//建立一个长度为4,容量为4的字符串切片
stringSlice := []string{"red", "yellow", "blue", "green"}
//建立一个空切片
nilSlice := []int{}
复制代码
请注意此方式与建立数组的区别,当中括号有具体数值时表示建立数组。ui
//建立一个有初始化元素的字符串数组
stringArr := [5]string{"red", "yellow", "blue", "green"}
复制代码
也能够指定长度。spa
//建立长度和容量为10的字符串切片
stringSlice := []string{9: "rainbow"}
复制代码
从一个切片中建立切片指针
slice := []int{1, 2, 3, 4, 5, 6}
//语法: 原切片[i:j:容量] //容量为可选,不指定时标识到原切片末尾
newSlice := slice[1:4] //newSlice为 [2, 3, 4]
复制代码
以上建立了一个长度为3,容量为5的切片。注意此处切片的长度为j-i
,j不是结束元素的索引。 前面了解了切片的底层,用此种方式建立的切片的会共享底层的数组,能够理解为,“从切片中切片”,那么修改切片会相互受到影响。code
slice[2] = 99
fmt.Println(newSlice[1]) //结果输出99
复制代码
从切片中切片↓
相较于数组,切片的一个优点是能够动态增加。经过append()
增加切片。 在此以前,了解一下两个内置函数len()
和cap()
,前者返回切片的长度,后者返回切片的容量。
//写个简单的函数输出切片长度、容量和内容
func echoStringSlice(slice []string) {
fmt.Printf("len: %d\n", len(slice))
fmt.Printf("cap: %d\n", cap(slice))
fmt.Println(slice)
}
//语法: append(原切片, ...新增原始) //第二参数为可变参数,能够添加任意多个
func main() {
stringSlice := []string{"red", "yellow", "blue", "green"}
echoStringSlice(stringSlice)
fmt.Println("After append...")
newSlice := append(stringSlice, "rainbow")
echoStringSlice(newSlice)
}
复制代码
编译运行后,结果为
len: 4
cap: 4
[red yellow blue green]
After append...
len: 5
cap: 8
[red yellow blue green rainbow]
复制代码
经过append()
函数会新生成一个切片,新生成的切片长度增加了,当切片的容量足够添加新的元素时,容量并不会发生改变,仅仅只是切片的长度变化,而当容量不足时则会动态增加底层数组,新生成的切片容量为原来的两倍(原容量小于1024时, 不然按增加因子0.25增加相应容量,随着数值的上升,增加因子可能会变得更小)
在函数间传递切片的空间开销是很小的。前面简单了解了切片的底层结构,那么在函数间传递切片时,切片在传递时大概只有一个指针、两个整形加起来那么大。而函数间传递数组时,须要复制整一个数组,对各方面的开销都是比较巨大的,固然也能够用指针来传递,但对指针操做稍不注意可能就会出现安全问题,且想要动态增加也没那么方便了。