## 一、切片定義
Go 數組的長度不可改變,在特定場景中這樣的集合就不太適用,Go 中提供了一種靈活,功能強悍的內置類型切片("動態數組"),與數組相比切片的長度是不固定的,可以追加元素,在追加時可能使切片的容量增大。
#### 1、語法:
~~~
var identifier []type
~~~
注:切片不需要說明長度。
#### 2、使用**make()**函數來創建切片:
~~~
var slice1 []type = make([]type, len)
也可以簡寫為
slice1 := make([]type, len)
~~~
#### 3、也可以指定容量,其中**capacity**為可選參數。
~~~
make([]T, length, capacity)
~~~
注:這里 len 是數組的長度并且也是切片的初始長度。
#### 4、切片的類型
切片(slice)是對數組一個連續片段的引用,所以切片是一個引用類型。
#### 5、切片的結構
切片有3個字段的數據結構:一個是指向底層數組的指針,一個是切片的長度,一個是切片的容量。
#### 切片實例
~~~
package main
import "fmt"
func main() {
//初始化切片
a1 := make([]int, 3)
a1[0] = 1
a1[1] = 2
a1[2] = 3
fmt.Println("a1的值為", a1)
a2 := []int{1, 2, 3}
fmt.Println("a2的值為", a2)
}
~~~
執行結果:
a1的值為 [1 2 3]
a2的值為 [1 2 3]
## 二、 len() 和 cap() 函數
切片是可索引的,并且可以由 len() 方法獲取長度。
切片提供了計算容量的方法 cap() 可以測量切片最長可以達到多少。
~~~
package main
import "fmt"
func printSlice(x []int) {
fmt.Printf("len=%d cap=%d slice=%v\n", len(x), cap(x), x)
}
func main() {
//初始化切片
a1 := make([]int, 3)
a1 = append(a1, 1)
fmt.Println("a1的值為", a1)
printSlice(a1)
}
~~~
執行結果:
a1的值為 [0 0 0 1]
len=4 cap=6 slice=[0 0 0 1]
## 三、空(nil)切片
~~~
package main
import "fmt"
func main() {
var numbers []int
printSlice(numbers)
if numbers == nil {
fmt.Printf("切片是空的")
}
}
func printSlice(x []int) {
fmt.Printf("len=%d cap=%d slice=%v\n", len(x), cap(x), x)
}
~~~
執行結果:
len=0 cap=0 slice=[]
切片是空的
## 四、切片截取
~~~
package main
import "fmt"
func main() {
/* 創建切片 */
numbers := []int{0, 1, 2, 3, 4, 5, 6, 7, 8}
/*
len=9 cap=9 slice=[0 1 2 3 4 5 6 7 8]
*/
printSlice(numbers)
/* 打印原始切片 */
//[0 1 2 3 4 5 6 7 8]
fmt.Println("numbers ==", numbers)
/* 打印子切片從索引1(包含) 到索引4(不包含)*/
//[1 2 3]
fmt.Println("numbers[1:4] ==", numbers[1:4])
/* 默認下限為 0*/
//[0 1 2]
fmt.Println("numbers[:3] ==", numbers[:3])
/* 默認上限為 len(s)*/
//[4 5 6 7 8]
fmt.Println("numbers[4:] ==", numbers[4:])
numbers1 := make([]int, 0, 5)
//len=0 cap=5 slice=[]
printSlice(numbers1)
/* 打印子切片從索引 0(包含) 到索引 2(不包含) */
number2 := numbers[:2]
//len=2 cap=9 slice=[0 1]
printSlice(number2)
}
func printSlice(x []int) {
fmt.Printf("len=%d cap=%d slice=%v\n", len(x), cap(x), x)
}
~~~
運行結果:
len=9 cap=9 slice=[0 1 2 3 4 5 6 7 8]
numbers == [0 1 2 3 4 5 6 7 8]
numbers[1:4] == [1 2 3]
numbers[:3] == [0 1 2]
numbers[4:] == [4 5 6 7 8]
len=0 cap=5 slice=[]
len=2 cap=9 slice=[0 1]
## 五、append() 和 copy() 函數
如果想增加切片的容量,我們必須創建一個新的更大的切片并把原分片的內容都拷貝過來。
下面的代碼描述了從拷貝切片的 copy 方法和向切片追加新元素的 append 方法。
~~~
package main
import "fmt"
func main() {
var numbers []int
printSlice(numbers)
/* 允許追加空切片 */
numbers = append(numbers, 0)
printSlice(numbers)
/* 向切片添加一個元素 */
numbers = append(numbers, 1)
printSlice(numbers)
/* 同時添加多個元素 */
numbers = append(numbers, 2, 3, 4)
printSlice(numbers)
/* 創建切片 numbers1 是之前切片的兩倍容量*/
numbers1 := make([]int, len(numbers), (cap(numbers))*2)
/* 拷貝 numbers 的內容到 numbers1 */
copy(numbers1, numbers)
printSlice(numbers1)
}
func printSlice(x []int) {
fmt.Printf("list=%v\n", x)
}
~~~
執行結果:
list=[]
list=[0]
list=[0 1]
list=[0 1 2 3 4]
list=[0 1 2 3 4]
## 六、切片的定義
方式一:通過make內置函數來創建切片。基本語法:?var切片名\[type?=?make(\[\],?len,\[cap\])

方式二:定一個切片,直接就指定具體數組,使用原理類似make的方式。

## 七、切片的遍歷
```
package?main
import?"fmt"
func?main(){
????????//定義切片:
????????slice?:=?make(\[\]int,4,20)
????????slice\[0\]?=?66
????????slice\[1\]?=?88
????????slice\[2\]?=?99
????????slice\[3\]?=?100
????????//方式1:普通for循環
????????for?i?:=?0;i?<?len(slice);i++?{
????????????????fmt.Printf("slice\[%v\]?=?%v?\\t"?,i,slice\[i\])
????????}
????????fmt.Println("\\n------------------------------")
????????//方式2:for-range循環:
????????for?i,v?:=?range?slice?{
????????????????fmt.Printf("下標:%v?,元素:%v\\n"?,i,v)
????????}
}
```
## 八、擴容機制

## 九、slice為什么不是線程安全
