Slice 跟陣列使用起來很像,而最大的不同是,陣列是值,Slice 是參考到一個陣列。
建立
要建立一個全新的 Slice 有兩種方法,一個是使用 make
函式:
package main
import "fmt"
func main() { slice := make([]int, 5)
fmt.Println(slice) }
|
另一個方法則是指定初值,雖然用法跟陣列很像,但形態不一樣就不能拿來一起比較。
package main
import "fmt" import "reflect"
func main() { slice := []int{1, 2, 3, 4, 5}
fmt.Println(slice)
arr := [...]int{1, 2, 3, 4, 5}
fmt.Println(reflect.TypeOf(slice)) fmt.Println(reflect.TypeOf(arr)) fmt.Println(arr == slice) }
|
Slice 是參考到一個陣列,可以看下面這個範列了解:
package main
import "fmt"
func main() { slice := []int{1, 2, 3, 4, 5} ref := slice
fmt.Println(slice) fmt.Println(ref)
slice[0] = 100
fmt.Println(slice) fmt.Println(ref)
ref[4] = 500
fmt.Println(slice) fmt.Println(ref) }
|
操作
我們可以對 Slice 做一些操作,如 len
函式可以查長度,cap
可以查參考的陣列有多少容量:
package main
import "fmt"
func main() { slice := []int{1, 2, 3}
fmt.Println(len(slice)) fmt.Println(cap(slice)) }
|
append
函式可以追加新元素在 Slice 最後面,下面是一個小範例:
package main
import "fmt"
func main() { slice1 := []int{1, 2, 3}
fmt.Println(slice1) fmt.Println(len(slice1)) fmt.Println(cap(slice1))
slice2 := append(slice1, 10)
fmt.Println(slice2) fmt.Println(len(slice2)) fmt.Println(cap(slice2))
slice3 := append(slice2, 20)
fmt.Println(slice3) fmt.Println(len(slice3)) fmt.Println(cap(slice3))
slice3[0] = 100 fmt.Println(slice1) fmt.Println(slice2) fmt.Println(slice3) }
|
上面可以觀察到 slice1
加入新元素產生出 slice2
有發生長度與容量的變化(長度 + 1,容量 * 2),並且最後面 slice1
與 slice2
的值並沒有參考到同個陣列。
另外 slice2
加入新元素產生出 slice3
只有長度 + 1 而已,最後面的值也有參考到同個陣列。
由此可知,當 Slice 新增元素超過了容量的時候,它會產生新的陣列,且容量有兩倍,給新的 Slice 參考;而容量夠用的時候,則不會產生新陣列。
copy
函式可以複製內容到另一個 Slice 裡,如下:
package main
import "fmt"
func main() { src := []int{1, 2, 3} dst1 := make([]int, 2) dst2 := make([]int, 3) dst3 := make([]int, 4)
fmt.Println(src) fmt.Println(dst1) fmt.Println(dst2) fmt.Println(dst3)
copy(dst1, src) copy(dst2, src) copy(dst3, src)
fmt.Println(src) fmt.Println(dst1) fmt.Println(dst2) fmt.Println(dst3)
src[0] = 100
fmt.Println(src) fmt.Println(dst1) fmt.Println(dst2) fmt.Println(dst3) }
|
複製時,即使長度不一還是會執行成功,只是會沒有複製完全。
從陣列或 Slice 產生 Slice
除了從頭建一個新的 Slice 外,也可以從陣列或 Slice 上產生新的 Slice,以下是簡單的範例
package main
import "fmt"
func main() { arr := [...]int{1, 2, 3, 4, 5}
slice := arr[1:4]
fmt.Println(slice) fmt.Println(len(slice)) fmt.Println(cap(slice))
slice2 := slice[1:3]
fmt.Println(slice2) fmt.Println(len(slice2)) fmt.Println(cap(slice2))
slice2[0] = 300
fmt.Println(arr) fmt.Println(slice) fmt.Println(slice2) }
|
[1:4]
代表的意思是,從「第 1 個元素開始,到第 4 個元素,不含第 4 個元素」,因此會取得 [2 3 4]
三個元素。而容量會從第 1 個元素開始,一直到結尾,以上例來說就是 4
。
下一個 [1:3]
相信就不難懂了,不過它會從 [2 3 4]
這個 Slice 取元素,所以會取到的是 [3 4]
,容量是 3
。
最後,因為沒有使用 append
函式,所以它們都參考到第一個陣列。
另外也可以使用 [:]
來取得全部陣列的內容。
參考資料