slice是一個序列的值,可以根據序列號來訪問??梢允褂?len(s) 返回 slice s 的長度。
寫一個例子,利用 for 循環,打印出 slice 的每一個值。利用下標來訪問每一個值。
package main
import (
"fmt"
)
func main() {
s := []int{1,1,2,3,5,8,13,21,34}
fmt.Println("slice s is", s)
for i := 0; i < len(s); i++ {
fmt.Printf("s[%d] == %d\n", i, s[i])
}
}
運行結果
slice s is [1 1 2 3 5 8 13 21 34]
s[0] == 1
s[1] == 1
s[2] == 2
s[3] == 3
s[4] == 5
s[5] == 8
s[6] == 13
s[7] == 21
s[8] == 34
slice的構成元素可以是任何類型,甚至也可以是其他slice。
比如:
game := [][]string{
[]string{"_","_","_"},
[]string{"_","_","_"},
[]string{"_","_","_"},
[]string{"_","_","_"},
[]string{"_","_","_"},
}
slice game的元素類型是 []string 的slice。
請看完整代碼
package main
import (
"fmt"
"strings"
)
func main() {
//填字游戲
game := [][]string{
[]string{"_","_","_"},
[]string{"_","_","_"},
[]string{"_","_","_"},
[]string{"_","_","_"},
[]string{"_","_","_"},
}
//玩家填寫的內容
game[0][0] = "X"
game[0][1] = "X"
game[0][2] = "X"
game[1][0] = "Y"
game[1][1] = "Y"
game[1][2] = "Y"
game[2][0] = "Z"
game[2][1] = "Z"
game[2][2] = "Z"
printGame(game)
}
func printGame(game [][]string) {
for i := 0; i < len(game); i++ {
fmt.Printf("%s\n", strings.Join(game[i], " "))
}
}
運行看看結果
X X X
Y Y Y
Z Z Z
_ _ _
_ _ _
任何一個slice都是對數組的一個切片后的使用。而且,它不影響原數組的值。
slice也可以重新切片。
像這樣
package main
import (
"fmt"
)
func main() {
s := []int{1,1,2,3,5,8,13,21,34,55}
fmt.Println("s ==", s)
fmt.Println("s[1:4] ==", s[1:4])
fmt.Println("s[2:5] ==", s[2:5])
//省略的寫法, : 符號左邊省略,表示從0開始
fmt.Println("s[:3] ==", s[:3])
//省略的寫法, : 符號右邊省略,表示到最后一個元素
fmt.Println("s[4:] ==", s[4:])
}
重新切片的切面,注意省略的寫法。
s == [1 1 2 3 5 8 13 21 34 55]
s[1:4] == [1 2 3]
s[2:5] == [2 3 5]
s[:3] == [1 1 2]
s[4:] == [5 8 13 21 34 55]
可以看到,此例中的多個slice都是針對同一個數組在操作。切片的切片的表達式是 s[lo:hi] 。
我們可以看到,hi 是不包含在新的slice內的。
所以,s[lo:lo] 是空的,而 s[lo:lo + 1] 有一個元素。
使用 make 創建 slice 的時候,可以使用第三個參數,指定容量。
容量用 cap() 表示。
b := make([]int, 0, 5) //創建一個slice,長度為0,容量為5
b = b[:cap(b)] //b的長度為5,容量為5
b = b[1:] //b的長度為4,容量為4
用一個列子,看一下slice容量的變化。
package main
import (
"fmt"
)
func main() {
a := make([]int, 5)
printSlice("a", a)
b := make([]int, 0, 5)
printSlice("b", b)
c := b[:2]
printSlice("c", c)
d := c[2:5]
printSlice("d", d)
}
func printSlice(s string, x []int) {
fmt.Printf("%s len=%d cap=%d %v\n", s, len(x), cap(x), x)
}
運行結果
a len=5 cap=5 [0 0 0 0 0]
b len=0 cap=5 []
c len=2 cap=5 [0 0]
d len=3 cap=3 [0 0 0]
新聲明的 slice 如果沒有賦值的話,它的零值是 nil 。長度和容量都是 0 。
以下代碼可證
package main
import (
"fmt"
)
func main() {
var z []int
fmt.Println(z, len(z), cap(z))
if z == nil {
fmt.Println("nil !")
}
}
運行結果
[] 0 0
nil !