0%

Go数组、切片与map

  • 数组
  • 切片
  • 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
    30
    31
    32
    33
    package main

    import (
    "fmt"
    )

    func main() {
    //一维数组
    var arr_1 [5] int
    fmt.Println(arr_1)

    var arr_2 = [5] int {1, 2, 3, 4, 5}
    fmt.Println(arr_2)

    arr_3 := [5] int {1, 2, 3, 4, 5}
    fmt.Println(arr_3)

    arr_4 := [...] int {1, 2, 3, 4, 5, 6}
    fmt.Println(arr_4)

    arr_5 := [5] int {0:3, 1:5, 4:6}
    fmt.Println(arr_5)

    //二维数组
    var arr_6 = [3][5] int {{1, 2, 3, 4, 5}, {9, 8, 7, 6, 5}, {3, 4, 5, 6, 7}}
    fmt.Println(arr_6)

    arr_7 := [3][5] int {{1, 2, 3, 4, 5}, {9, 8, 7, 6, 5}, {3, 4, 5, 6, 7}}
    fmt.Println(arr_7)

    arr_8 := [...][5] int {{1, 2, 3, 4, 5}, {9, 8, 7, 6, 5}, {0:3, 1:5, 4:6}}
    fmt.Println(arr_8)
    }
    运行结果:
    image

    注意事项

  • 数组的长度固定,len()cap() 的结果是一样的
  • 函数传参为值传递,传的是拷贝

Slice 切片

切片是动态数组,长度可变,可以进行追加 append() 和截取 s[x:y]
len()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
26
27
28
29
30
package main

import "fmt"

func main() {
var numbers = make([]int, 3, 5)

fmt.Printf("len = %d, cap = %d, slice = %v\n", len(numbers), cap(numbers), numbers)

//向numbers切片追加一个元素1, numbers len = 4, [0,0,0,1], cap = 5
numbers = append(numbers, 1)

fmt.Printf("len = %d, cap = %d, slice = %v\n", len(numbers), cap(numbers), numbers)

//向numbers切片追加一个元素2, numbers len = 5, [0,0,0,1,2], cap = 5
numbers = append(numbers, 2)

fmt.Printf("len = %d, cap = %d, slice = %v\n", len(numbers), cap(numbers), numbers)

//向一个容量cap已经满的slice 追加元素,
numbers = append(numbers, 3)

fmt.Printf("len = %d, cap = %d, slice = %v\n", len(numbers), cap(numbers), numbers)

fmt.Println("---------")
var numbers2 = make([]int, 3)
fmt.Printf("len = %d, cap = %d, slice = %v\n", len(numbers2), cap(numbers2), numbers2)
numbers2 = append(numbers2, 1)
fmt.Printf("len = %d, cap = %d, slice = %v\n", len(numbers2), cap(numbers2), numbers2)
}

运行结果:

注意事项:

  • 切片为引用传递
  • 切片扩容会新建一个切片(容量为两倍),返回一个变量指向新的地址,原变量仍然指向旧的地址,因此可能出现扩容的地方都需要接收返回值。

    Append returns the updated slice. It is therefore necessary to store the result of append, often in the variable holding the slice itself.

切片截取与拷贝

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package main

import "fmt"

func main() {
s := []int{1, 2, 3} //len = 3, cap = 3, [1,2,3]

//[0, 2)
s1 := s[0:2] // [1, 2]
fmt.Println(s1)

s1[0] = 100

fmt.Println(s)
fmt.Println(s1)

//copy 可以将底层数组的slice一起进行拷贝
s2 := make([]int, 3) //s2 = [0,0,0]

//将s中的值 依次拷贝到s2中
copy(s2, s)
fmt.Println(s2)
}

运行结果:

注意事项

  • 每次扩容为之前容量的两倍
  • 切片直接赋值 ss := s 与切片截取后,两个指针指向同一块区域,使用 copy() 进行深拷贝

map

map 也是引用传递

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
30
31
32
33
34
35
36
37
38
package main

import "fmt"

func main() {
//===> 第一种声明方式

//声明myMap1是一种map类型 key是string, value是string
var myMap1 map[string]string
if myMap1 == nil {
fmt.Println("myMap1 是一个空map")
}

//在使用map前, 需要先用make给map分配数据空间
myMap1 = make(map[string]string, 10)

myMap1["one"] = "java"
myMap1["two"] = "c++"
myMap1["three"] = "python"

fmt.Println(myMap1)

//===> 第二种声明方式
myMap2 := make(map[int]string)
myMap2[1] = "java"
myMap2[2] = "c++"
myMap2[3] = "python"

fmt.Println(myMap2)

//===> 第三种声明方式
myMap3 := map[string]string{
"one": "php",
"two": "c++",
"three": "python",
}
fmt.Println(myMap3)
}

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
30
31
32
33
34
35
36
37
38
39
package main

import "fmt"

func printMap(cityMap map[string]string) {
//cityMap 是一个引用传递
for key, value := range cityMap {
fmt.Println("key = ", key)
fmt.Println("value = ", value)
}
}

func ChangeValue(cityMap map[string]string) {
cityMap["England"] = "London"
}

func main() {
cityMap := make(map[string]string)

//添加
cityMap["China"] = "Beijing"
cityMap["Japan"] = "Tokyo"
cityMap["USA"] = "NewYork"

//遍历
printMap(cityMap)

//删除
delete(cityMap, "China")

//修改
cityMap["USA"] = "DC"
ChangeValue(cityMap)

fmt.Println("-------")

//遍历
printMap(cityMap)
}