go基础语法之map

map定义

go中,提供映射关系的容器为map,内部用hash表实现;

何为map

map是一种无序的基于k-v的数据结构,go中的map是引用类型,必须先初始化才能使用

map类型的变量,声明后:初始值为nil,使用make函数来分配内存,才可使用,(否则会报错

声明语法

1
2
3
4
map[keyType]valueType

// keyType键的类型
// valueType值的类型
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
package main

import "fmt"

func main() {
	// 只声明一个map变量m1,但并没初始化,其没有分配任何内存,"值"等于nil
	var m1 map[string]int
	fmt.Println(m1 == nil)
	m1["wang"] = 24
	
	// 此时使用会报错:panic: assignment to entry in nil map
}

ten@LAPTOP-5TPRJ6VQ MINGW64 /d/workstation/mycode/gocode/src/learngo/basic_grammar/07map (master)
$ go run main.go 
true
panic: assignment to entry in nil map

goroutine 1 [running]:
main.main()
        D:/workstation/mycode/gocode/src/learngo/basic_grammar/07map/main.go:9 +0xb9
exit status 2

初始化语法

1
2
3
make(map[keytype]valuetype,[cap])

// cap指定了map的容量,非必须,但应该初始化时,就预估好容量

初始化分配内存:

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

import "fmt"

func main() {
	// 只声明一个map变量m1,但并没初始化,其没有分配任何内存,"值"等于nil
	var m1 map[string]int
	fmt.Println(m1 == nil)
    
	// m1["wang"] = 24
	// make函数,为m1初始化,给其分配内存,不再等于nil,
	m1 = make(map[string]int, 6)
	m1["wang"] = 24
	fmt.Println(m1 == nil)
	fmt.Println(m1)

}
ten@LAPTOP-5TPRJ6VQ MINGW64 /d/workstation/mycode/gocode/src/learngo/basic_grammar/07map (master)
$ go run main.go 
true
false
map[wang:24]

map基础使用

值填充

1,定义后填充值

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

import "fmt"
// map使用
func main()  {
	scoreMap := make(map[string]int, 8)
	scoreMap["wang"] = 100
	scoreMap["li"] 		= 80
	fmt.Println(scoreMap)

	fmt.Println(scoreMap["wang"])
	fmt.Printf("type of scoreMap:%T\n", scoreMap)
}

ten@LAPTOP-5TPRJ6VQ MINGW64 /d/workstation/mycode/gocode/src/learngo/basic_grammar/07map (master)
$ go run main.go 
map[li:80 wang:100]
100
type of scoreMap:map[string]int

2,声明时,就填充值

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
package main

import "fmt"

// 声明时,即赋值
func main()  {
	userInfo := map[string]string{
		"username": "wang",
		"Passwd": "wang",
	}
	fmt.Println(userInfo)
}

ten@LAPTOP-5TPRJ6VQ MINGW64 /d/workstation/mycode/gocode/src/learngo/basic_grammar/07map (master)
$ go run main.go 
map[Passwd:wang username:wang]

判断某key是否存在

 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
package main

import "fmt"

// 判断map中某键是否存在


func main()  {
	// value, ok := map[key]
	// value和ok可自定义,但一般为它们,见明知意,key为要判断的key
	m1 := make(map[string]int)
	fmt.Println(m1 == nil)
	m1["wang"] = 100
	m1["li"] = 99
	v, ok := m1["wang"]
	if ok {
		fmt.Println(v)
		fmt.Println("wang is exist")
	}else {
		fmt.Println("wang is no exist")
	}
	v1, ok1 := m1["haha"]
	if ok1 {
		fmt.Println(v1)
		fmt.Printf("haha is exist")
	}else {
		fmt.Println("haha is not exist")
	}
}

ten@LAPTOP-5TPRJ6VQ MINGW64 /d/workstation/mycode/gocode/src/learngo/basic_grammar/07map (master)
$ go run main.go 
false
100
wang is exist
haha is not exist

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
package main

import "fmt"


// 遍历map
func main()  {
	m1 := make(map[string]int, 10)
	m1["wang"] = 100
	m1["li"] = 10
	m1["zhou"] = 1
    // 遍历键和值
	for k, v := range m1 {
		fmt.Println(k,v)
	}

	// 只遍历key
	for _,v := range m1 {
		fmt.Println(v)
	}
	// 只遍历value
	for k := range m1 {
		fmt.Println(k)
	}
}

ten@LAPTOP-5TPRJ6VQ MINGW64 /d/workstation/mycode/gocode/src/learngo/basic_grammar/07map (master)
$ go run main.go 
wang 100
zhou 1
li 10 
100   
1     
10    
li    
zhou  
wang  

delete删除键值

 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() {

	scoreTable := make(map[string]int, 10)

	scoreTable["wang"] = 100
	scoreTable["li"] = 90
	scoreTable["lin"] = 80

	delete(scoreTable, "wang")

	for k, v := range scoreTable {
		fmt.Println(k, v)
	}
}	

ten@LAPTOP-5TPRJ6VQ MINGW64 /d/workstation/mycode/gocode/src/learngo/basic_grammar/07map (master)
$ go run main.go 
lin 80
li 90

按照指定顺序遍历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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
package main

import (
	"fmt"
	"math/rand"
	"sort"
	"time"
)

// 使得无序存放的map,按照顺序输出,思路:将map的所有key取出放在一个切片中,利用排序函数对切片进行排序,然后遍历切片,根据切片中排序好的key,打印的也是排序好后的map

func main() {
	rand.Seed(time.Now().UnixNano()) // 初始化随机数种子

	var scoreTable = make(map[string]int, 20) // 声明并初始化一个容量为20的map

	// 先根据生成的随机字符串,组成一组无序的,map键值
	for i := 0; i < 10; i++ {
		key := fmt.Sprintf("stu%02d", i) // 生成stu开头的字符串
		value := rand.Intn(10)

		scoreTable[key] = value // 向map中填入10个键值对
	}
	fmt.Println("这是无序的")
	for k, v := range scoreTable {
		fmt.Println(k, v)
	}

	fmt.Println("这是排序后")
	// 取出map中的key,放入一个切片中
	var keys = make([]string, 0, 20)
	for i := range scoreTable {
		keys = append(keys, i)
	}
	// 对切片利用sort函数,进行排序
	sort.Strings(keys)
	// 根据排序后的切片,依次打印,进而打印出有序的map
	for _, key := range keys {
		fmt.Println(key, scoreTable[key])
	}
}
ten@LAPTOP-5TPRJ6VQ MINGW64 /d/workstation/mycode/gocode/src/learngo/basic_grammar/07map (master)
$ go run main.go 
这是无序的
stu01 3
stu02 2
stu04 9
stu08 3
stu05 9
stu06 0
stu00 8
stu07 7
stu03 0
stu09 8
这是排序后
stu00 8
stu01 3
stu02 2
stu03 0
stu04 9
stu05 9
stu06 0
stu07 7
stu08 3
stu09 8

元素为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"
)

// 元素类型为map的切片:

func main() {
	var mapSlice = make([]map[string]string, 3)
	for k, v := range mapSlice {
		fmt.Printf("key: %v, value: %v \n", k, v)
	} // 定义并初始化,一个切片,其每个元素都是一个map类型

	// 初始化切片的第一个元素,即一个map,用make分配内存
	mapSlice[0] = make(map[string]string, 3)

	// 向其中填充值
	mapSlice[0]["name"] = "wang"
	mapSlice[0]["age"] = "18"
	mapSlice[0]["passwd"] = "123"

	mapSlice[1] = make(map[string]string, 2)
	mapSlice[1]["name"] = "wang"
	mapSlice[1]["shuai"] = "haha"
	for k, v := range mapSlice {
		fmt.Printf("key: %v, value: %v \n", k, v)
	}

}

ten@LAPTOP-5TPRJ6VQ MINGW64 /d/workstation/mycode/gocode/src/learngo/basic_grammar/07map (master)
$ go run main.go 
key: 0, value: map[] 
key: 1, value: map[] 
key: 2, value: map[]
key: 0, value: map[age:18 name:wang passwd:123]
key: 1, value: map[name:wang shuai:haha]
key: 2, value: 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
package main

import "fmt"

// 键值对中,其值为切片类型,的map

func main() {
	var sliceMap = make(map[string][]string, 0)
	fmt.Println(sliceMap)

	fmt.Println("after init")

	// 定义一个键,先判断该键是否在map中,
	// 如果不在,就将该键对应的值,初始化为一个,string类型的切片,长度为0
	// 之后,对该切片追加2个元素
	// 最后,将键、和值,添加到map中,打印map即可
	k1 := "中国"
	value, ok := sliceMap[k1]
	if !ok {
		value = make([]string, 0)
	}
	value = append(value, "上海", "杭州")

	sliceMap[k1] = value

	fmt.Println(sliceMap)
}
ten@LAPTOP-5TPRJ6VQ MINGW64 /d/workstation/mycode/gocode/src/learngo/basic_grammar/07map (master)
$ go run main.go 
map[]
after init
map[中国:[上海 杭州]]

练习

  1. 写一个程序,统计一个字符串中每个单词出现的次数。比如:”how do you do”中how=1 do=2 you=1。

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    
    package main
       
    import "fmt"
       
       
       
    func main() {
     s1 := make([]string, 0,4)
     s1 = append(s1, "how", "do", "you", "do")
     fmt.Println(s1)
     m1 := make(map[string]int)
       
     for _, v := range s1 {
         m1[v] = m1[v] + 1
     }
     fmt.Println(m1)
    }
    ten@LAPTOP-5TPRJ6VQ MINGW64 /d/workstation/mycode/gocode/src/learngo/basic_grammar/07map (master)
    $ go run main.go 
    [how do you do]
    map[do:2 how:1 you:1]
    
  2. 观察下面代码,写出最终的打印结果。

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    
    // 没整明白?
    package main
       
    import "fmt"
    func main() {
     type Map map[string][]int
     m := make(Map)
     s := []int{1, 2}
     s = append(s, 3)
     fmt.Printf("%+v\n", s)
     m["q1mi"] = s
     s = append(s[:1], s[2:]...)
     fmt.Printf("%+v\n", s)
     fmt.Printf("%+v\n", m["q1mi"])
    }
    ten@LAPTOP-5TPRJ6VQ MINGW64 /d/workstation/mycode/gocode/src/learngo/basic_grammar/07map (master)
    $ go run main.go 
    [1 2 3]
    [1 3]
    [1 3 3]
    
updatedupdated2021-03-092021-03-09
加载评论