容器类型
数组
数组 是一个由 固定长度 的特定类型元素组成的序列,一个数组可以由零个或多个元素组成。
[3]int 和 [5]int 是不同的类型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| package main
import "fmt"
func fun1() { var a [5]int a[1] = 2 fmt.Println(a) }
func fun2() { var a = [5][2]int{{1, 2}, {3, 4}} fmt.Println(a)
}
func fun3() { var arr1 = [5]int{15, 20, 25, 30, 35} fmt.Println(arr1)
arr2 := [5]int{15, 20, 25, 30, 35} fmt.Println(arr2)
arr3 := [5]int{15, 20} fmt.Println(arr3)
arr4 := [5]int{1: 100, 4: 200} fmt.Println(arr4)
arr5 := [...]int{15, 20, 25, 30, 35, 40} fmt.Println(arr5) }
func main() { fun2() }
|
len函数
使用内置的 len
函数将返回数组中元素的个数,即数组的长度。
1 2
| arr := [...]int{1,2,3,4} fmt.Println(len(arr))
|
数组遍历
使用 for range
循环可以获取数组每个索引以及索引上对应的元素。
1 2 3 4 5 6 7 8 9 10
| func showArr() { arr := [...]int{1, 2, 3} for index, value := range arr { fmt.Printf("arr[%d]=%s\n", index, value) }
for _, value := range arr { fmt.Printf("value=%s\n", value) } }
|
数组是值类型
Go 中的数组是值类型而不是引用类型。当数组赋值给一个新的变量时,该变量会得到一个原始数组的一个副本。如果对新变量进行更改,不会影响原始数组.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| func arrByValue() { arr := [...]string{"1", "02", "03"} b := arr b[0] = "01" fmt.Println(arr) fmt.Println(b) }
|
切片(Slice)
切片是对数组的一个连续片段的引用,所以切片是一个引用类型。切片 本身不拥有任何数据,它们只是对现有数组的引用,每个切片值都会将数组作为其底层的数据结构。slice 的语法和数组很像,只是没有固定长度而已。
切片的声明
make
函数构造一个切片,格式为 make([]Type, size, cap)
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| package main
import "fmt"
func fun1() { var arr1 []int arr1 = append(arr1, 1) fmt.Println(arr1)
var arr2 = []int{} fmt.Println(arr2) }
func fun2() { arr1 := make([]int, 3, 5) fmt.Println(arr1) }
func main() { fun2() }
|
切片的长度和容量
1 2 3
| s := make([]string, 3, 5) fmt.Println(len(s)) fmt.Println(cap(s))
|
切片是引用类型
由于 slice 是引用类型,所以你不对它进行赋值的话,它的默认值是 nil
切片之间不能比较,因此我们不能使用 ==
操作符来判断两个 slice 是否含有全部相等元素。特别注意,如果你需要测试一个 slice 是否是空的,使用 len(s) == 0
来判断,而不应该用 s == nil
来判断。
元素修改
切片自己不拥有任何数据。它只是底层数组的一种表示。对切片所做的任何修改都会反映在底层数组中.
1 2 3 4 5 6 7 8
| var arr = [...]string{"11", "22", "33"} s := arr[:] fmt.Println(arr) fmt.Println(s)
s[0] = "aa" fmt.Println(arr) fmt.Println(s)
|
元素追加
当新的元素被添加到切片时,如果容量不足,会创建一个新的数组。现有数组的元素被复制到这个新数组中,并返回新的引用。现在新切片的容量是旧切片的两倍。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| s := []string{"11"} fmt.Println(s) fmt.Println(cap(s))
s = append(s, "22") fmt.Println(s) fmt.Println(cap(s))
s = append(s, "33", "44") fmt.Println(s) fmt.Println(cap(s))
s = append(s, []string{"55", "66"}...) fmt.Println(s) fmt.Println(cap(s))
|
元素删除
删除slice中间的某个元素并保存原有的元素顺序,可以通过内置的copy函数将后面的子slice向前依次移动一位完成:
1 2 3 4 5 6 7 8 9
| func remove(slice []int, i int) []int { copy(slice[i:], slice[i+1:]) return slice[:len(slice)-1] }
func main() { s := []int{5, 6, 7, 8, 9} fmt.Println(remove(s, 2)) }
|
如果删除元素后不用保持原来顺序的话,我们可以简单的用最后一个元素覆盖被删除的元素:
1 2 3 4
| func remove(slice []int, i int) []int { slice[i] = slice[len(slice)-1] return slice[:len(slice)-1] }
|
Map
在 Go 语言中,map 是散列表(哈希表)的引用(引用类型)。
使用 make
函数传入键和值的类型,可以创建 map 。具体语法为 make(map[KeyType]ValueType)
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| mp1 := make(map[string]int) mp2 := make(map[string]string)
var mp3 map[string]string = map[string]string{ "1": "aa", "2": "bb", "3": "cc", } fmt.Println(mp3)
mp4 := map[string]string{ "aa": "11", "bb": "22", "cc": "33", } fmt.Println(mp4)
|
Map 操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
|
mp1["11"] = "aa"
mp1["11"] = "AAA"
fmt.Println(mp1["11"] )
delete(mp1, "11")
v3, ok := mp1["22"] fmt.Println(ok) fmt.Println(v3)
for key, value := range mp1 { fmt.Printf("key: %s, value: %d\n", key, value) }
fmt.Println(len(mp1))
|