在介紹陣列時,大家有沒有發現每次宣告陣列時都要去宣告長度,而且長度是宣告後就不能改變的。
接下來介紹一個比陣列更有彈性的組合型別-切片(slice)。
切片有三個部分組成:
package main
import "fmt"
func main(){
role := [...]string{"董事長","總經理","副理","課長","一般員工"}
slice := role[0:3]
fmt.Println(slice)
fmt.Println(role) // Array
fmt.Println(len(slice)) // Length
fmt.Println(cap(slice)) // Capacity
}
執行結果:
[董事長 總經理 副理]
[董事長 總經理 副理 課長 一般員工]
3
5
第 4 行就是基本的宣告陣列的方式,來看第 5 行的 slice := role[0:3]
,這是甚麼意思?
它的意思是,我在 index = 0
的左邊切一刀,再到 index = 3
的左邊切一刀。
這樣 slice
就會從 role
中挑出 0, 1, 2
形成切片。
所以執行的結果才會是 [董事長 總經理 副理]
length
指的是 slice
過後的陣列長度,也就是 3
。Capacity
指的是原本陣列 role
的長度,也就是 5
。
所以可以利用指向不同的陣列,可以實現容量、長度都可以變動的切片。
除了直接從陣列切出來,也可以用 make
來宣告一個新的切片 slice
。
:::info
變數名稱 := make([]資料型態, length, capacity)
:::
package main
import "fmt"
func main(){
slice := make([]sting, 3, 5) // 變數名稱可以取自己喜歡的名字
slice[0] = "董事長"
slice[1] = "總經理"
slice[2] = "副理"
fmt.Println(slice)
fmt.Println(len(slice))
fmt.Println(cap(slice))
}
執行結果:
[董事長 總經理 副理]
3
5
第 4 行用 make
宣告新的切片,後面宣告切片型態,也就是 []string
或是 []int
,接著,後面填入 length
及 capacity
。
第 9 行印出 slice
的長度 len
,第 10 行印出 slice
的容量 cap
。
宣告時可以省略第 3 個參數 capacity
,如果只有指定第 2 參數,那就代表宣告一個長度
與容量
相同的 slice
。
package main
import "fmt"
func main(){
slice := make([]string, 5)
slice[0] = "董事長"
slice[1] = "總經理"
slice[2] = "副理"
fmt.Println(slice)
fmt.Println(len(slice))
fmt.Println(cap(slice))
}
執行結果:
[董事長 總經理 副理]
5
5
除了可以用 make
宣告外,還可以用跟宣告陣列的方法來宣告。
package main
import "fmt"
func main(){
slice := []string{"董事長","總經理","副理","課長"}
fmt.Println(slice)
fmt.Println(len(slice))
fmt.Println(cap(slice))
}
執行結果:
[董事長 總經理 副理 課長]
4
4
:::warning
這邊要注意,在宣告切片時,是用 []string{}
。
宣告陣列時,適用 [...]string{}
。
:::
宣告切片時,如果不確定要用多少容量,可以先宣告一個空切片,並且使用 append()
來插入新的值。
使用 append()
時,可以不考慮切片的容量,Go 會自己解決。
package main
import "fmt"
func main(){
slice := []string{} // 宣告空切片
slice = append(slice, "董事長")
slice = append(slice, "總經理")
slice = append(slice, "副理")
slice = append(slice, "課長")
fmt.Println(slice)
fmt.Println(len(slice)) // 長度
fmt.Println(cap(slice)) // 容量
}
執行結果:
[董事長 總經理 副理 課長]
4
4
切片 ( slice
) 跟陣列一樣可以利用 for
進行走訪。
package main
import "fmt"
func main(){
slice := []string{"董事長", "總經理", "副理", "課長"}
for i := 0; i < len(slice); i ++{
fmt.Printf("%d : %s\n", i, slice[i])
}
}
執行結果:
0 : 董事長
1 : 總經理
2 : 副理
3 : 課長
slice
跟陣列一樣可以用 for range
進行巡迴切片,其規則跟走訪陣列一樣。
package main
import "fmt"
func main(){
slice := []string{"董事長", "總經理", "副理", "課長"}
for k, v := range slice{
fmt.Printf("%d : %s\n", k, v)
}
}
執行結果:
0 : 董事長
1 : 總經理
2 : 副理
3 : 課長