Go学习笔记: 切片

在实际开发中,大多数状况处理的数据都不是单一的,而是复数的同类型数据。全部的高级语言都会封装相应的数据结构、API等。在Go语言中,提供了数组、切片以及映射三种数据结构供开发者管理和处理集合数据。切片基于数组,却有别于数组,本次笔记学习Go切片相关的内容。数组

切片结构

为了更方便学习切片的内容,首先简单了解一下切片的底层长什么样。 安全

img
由上图,一个切片有三个项,长度,容量以及指向数组的指针,即切片是创建在数组的基础上的。建立切片时,底层的数组容量为切片的指定容量,切片在使用时,可用的空间只有切片指定长度的空间。设置容量为底层的数组提供一层保护。当切片动态增加时,才会影响切片的容量。

建立切片

使用内置数据结构的第一步:声明建立初始化。 切片有三种建立方式 使用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
复制代码

从切片中切片↓

img

切片扩容

相较于数组,切片的一个优点是能够动态增加。经过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增加相应容量,随着数值的上升,增加因子可能会变得更小)

函数间传递切片

在函数间传递切片的空间开销是很小的。前面简单了解了切片的底层结构,那么在函数间传递切片时,切片在传递时大概只有一个指针、两个整形加起来那么大。而函数间传递数组时,须要复制整一个数组,对各方面的开销都是比较巨大的,固然也能够用指针来传递,但对指针操做稍不注意可能就会出现安全问题,且想要动态增加也没那么方便了。

相关文章
相关标签/搜索