目录
数组
数组简述
类型 [n]T
表示拥有 n
个 T
类型的值的数组。
表达式
var a [10]int
//将变量 a 声明为拥有 10 个整数的数组
数组的长度是其类型的一部分,因此数组不能改变大小。这看起来是个限制,不过没关系,Go 提供了更加便利的方式来使用数组。
package main
import "fmt"
func main() {
var a [2]string
a[0] = "Hello"
a[1] = "World"
fmt.Println(a[0], a[1])
fmt.Println(a)
primes := [6]int{
1, 2, 3, 4, 5, 6}
fmt.Println(primes)
}
//Hello World
//[Hello World]
//[1 2 3 4 5 6]
切片
每个数组的大小都是固定的,而切片则为数组元素提供动态大小的、灵活的视角。
在实践中,切片比数组更常用。
类型 []T
表示一个元素类型为 T
的切片。
切片通过两个下标来界定,即一个上界和一个下界,二者以冒号分隔:
a[low : high]
它会选择一个半开区间,包括第一个元素,但排除最后一个元素。
以下表达式创建了一个切片,它包含 a
中下标从 1 到 3 的元素:
a[1:4]
package main
import "fmt"
func main() {
primes := [6]int{
1, 2, 3, 4, 5, 6}
var s []int = primes[1:4]
fmt.Println(s)
fmt.Printf("切片长度为:%d", len(s)) //长度等于元素个数,上界-下界=元素个数
fmt.Printf("切片容量为:%d", cap(s))
}
//[2 3 4]
//切片长度为:3
//切片容量为:5
更改切片
切片并不存储任何数据,它只是描述了底层数组中的一段。
更改切片的元素会修改其底层数组中对应的元素,与它共享底层数组的切片都会观测到这些修改。
package main
import "fmt"
func main() {
names := [4]string{
"John",
"Paul",
"George",
"Ringo",
} //这个是数组
fmt.Println(names)
a := names[0:2] //这是个切片
b := names[1:3] //这是个切片
fmt.Println(a, b)
b[0] = "XXX"
fmt.Println(a, b)
fmt.Println(names)
}
//[John Paul George Ringo]
//[John Paul] [Paul George]
//[John XXX] [XXX George]
//[John XXX George Ringo]
切片的默认行为
在进行切片时,你可以利用它的默认行为来忽略上下界。
切片下界的默认值为 0
,上界则是该切片的长度。
对于数组
var a [10]int
来说,以下切片是等价的:
a[0:10]
a[:10]
a[0:]
a[:]
切片的长度与容量
切片拥有 长度 和 容量。
切片的长度就是它所包含的元素个数。
切片的容量是从它的第一个元素开始数,到其底层数组元素末尾的个数。
切片 s
的长度和容量可通过表达式 len(s)
和 cap(s)
来获取。
只要具有足够的容量,你就可以通过重新切片来扩展一个切片。
package main
import "fmt"
func main() {
s := []int{
2, 3, 5, 7, 11, 13}
printSlice(s)
// 截取切片使其长度为 0
s = s[:0]
printSlice(s)
// 拓展其长度
s = s[:4]
printSlice(s)
// 舍弃前两个值
s = s[2:]
printSlice(s)
}
func printSlice(s []int) {
fmt.Printf("len=%d cap=%d %v\n", len(s), cap(s), s)
}
nil 切片
切片的零值是 nil
。
nil 切片的长度和容量为 0 且没有底层数组。
用 make 创建切片(实际常用)
切片可以用内建函数 make
来创建,这也是你创建动态数组的方式。
make
函数会分配一个元素为零值的数组并返回一个引用了它的切片:
a := make([]int, 5) // len(a)=5
要指定它的容量,需向 make
传入第三个参数:
b := make([]int, 0, 5) // len(b)=0, cap(b)=5
b = b[:cap(b)] // len(b)=5, cap(b)=5
b = b[1:] // len(b)=4, cap(b)=4
切片的切片
切片可包含任何类型,甚至包括其它的切片。
package main
import (
"fmt"
"strings"
)
func main() {
// 创建一个井字板(经典游戏)
board := [][]string{
[]string{
"_", "_", "_"},
[]string{
"_", "_", "_"},
[]string{
"_", "_", "_"},
}
// 两个玩家轮流打上 X 和 O
board[0][0] = "X"