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 !