请选择 进入手机版 | 继续访问电脑版

 找回密码
 立即注册
搜索
查看: 297|回复: 0

[go基础] 《Go语言入门指南》学习笔记 - Map字典

  [复制链接]
匿名
匿名  发表于 2023-2-8 16:27 |阅读模式

map 字典 特点:

  • 元素对
  • 无序集合

0x01 Map 声明、初始化和 make

0x001 map 概念

声明格式:

1
2
var map1 map[keytype]valuetype
var map1 map[string]int

说明:

  • 在声明的时候不需要知道 map 的长度,map 是可以动态增长的。
  • 未初始化的 map 的值是 nil。
  • key 可以是任意用 == 或 != 操作符比较的类型,例如 string,int,float,结构体可以,但是需要计算唯一key
  • value 任意类型

map 元素赋值


map1[key] = val1

计算 map 长度

len(map1)

map 初始化

1
2
var map1 = make(map[keytype]valuetype)
map1 := make[map[keytype]valuetype] // 简写形式 相当于 map1 := map[keytype]valuetype{}

注意:不要使用 new,永远用 make 来构造 map

示例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
package main
import "fmt"

func main() {
  // map value 类型为 func() int 
    mf := map[int]func() int{
        1: func() int { return 10 },
        2: func() int { return 20 },
        5: func() int { return 50 },
    }
    fmt.Println(mf)
}

0x002 map 容量

出于性能的考虑,对于大的 map 或者会快速扩张的 map,即使只是大概知道容量,也最好先标明。


map2 := make(map[string]float32, 100)

0x003 用切片作为 map 的值

例如父进程( pid 为整型)作为key,所有子进程作为value ( 以所有的子进程的 pid 组成的切片 )

1
2
mp1 := make(map[int][]int)
mp2 := make(map[int]*[]int)

0x02 测试键值对是否存在及删除元素

判断键值对是否存在


var1, isPresent = map1[key1]

说明:

  • var1 : key1 对应的 value 值
  • isPresent : 返回一个 bool 值,如果存在 key1 存在于 map1 ,isPresent 为 true,否则为false
1
2
3
if _, ok := map1[key1]; ok {
    // ...
}

删除key:


delete(map1,key1) // 从 map1 中删除 key1

0x03 for-range 的配套用法

循环 map 元素

1
2
3
for key, value := range map1 {
		...
}

只获取值

1
2
3
for _, value := range map1 {
		...
}

只获取key

1
2
3
for key := range map1 {
		...
}

0x04 map 类型的切片

 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() {
    // Version A:
    items := make([]map[int]int, 5)
    for i:= range items {
        items[i] = make(map[int]int, 1)
        items[i][1] = 2
    }
    fmt.Printf("Version A: Value of items: %v\n", items)

    // Version B: NOT GOOD!
    items2 := make([]map[int]int, 5)
    for _, item := range items2 {
        item = make(map[int]int, 1) // item is only a copy of the slice element.
        item[1] = 2 // This 'item' will be lost on the next iteration.
    }
    fmt.Printf("Version B: Value of items: %v\n", items2)
}

输出结果:

Version A: Value of items: [map[1:2] map[1:2] map[1:2] map[1:2] map[1:2]]
Version B: Value of items: [map[] map[] map[] map[] map[]]

说明:

应当像 A 版本那样通过索引使用切片的 map 元素。

在 B 版本中获得的项只是 map 值的一个拷贝而已,所以真正的 map 元素没有得到初始化

0x05 map 的排序

默认无序,不管是按照 key,还是 value ,默认都不排序。

如果要为 map 排序:

首先将 key (或者 value )copy 到一个切片,

再对切片使用 sort 包 排序,

然后再使用切片的 for-range 方法打印出所有的 key 和 value。

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
// the telephone alphabet:
package main
import (
    "fmt"
    "sort"
)

var (
    barVal = map[string]int{"alpha": 34, "bravo": 56, "charlie": 23,
                            "delta": 87, "echo": 56, "foxtrot": 12,
                            "golf": 34, "hotel": 16, "indio": 87,
                            "juliet": 65, "kili": 43, "lima": 98}
)

func main() {
    fmt.Println("unsorted:")
    for k, v := range barVal {
        fmt.Printf("Key: %v, Value: %v / ", k, v)
    }
    keys := make([]string, len(barVal))
    i := 0
    for k, _ := range barVal {
        keys[i] = k
        i++
    }
    sort.Strings(keys)
    fmt.Println()
    fmt.Println("sorted:")
    for _, k := range keys {
        fmt.Printf("Key: %v, Value: %v / ", k, barVal[k])
    }
}

如果想要一个排序的列表,使用结构体切片

1
2
3
4
type name struct {
    key string
    value int
}

0x06 将 map 的键值对调

对调的前提:map 的值类型可以作为 key 且所有的 value 是唯一

 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"
)

var (
    barVal = map[string]int{"alpha": 34, "bravo": 56, "charlie": 23,
                            "delta": 87, "echo": 56, "foxtrot": 12,
                            "golf": 34, "hotel": 16, "indio": 87,
                            "juliet": 65, "kili": 43, "lima": 98}
)

func main() {
    invMap := make(map[int]string, len(barVal))
    for k, v := range barVal {
        invMap[v] = k // 对调 key 和 value
    }
    fmt.Println("inverted:")
    for k, v := range invMap {
        fmt.Printf("Key: %v, Value: %v / ", k, v)
    }
}

 

原文地址:http://www.manoner.com/post/GoLand/Go%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%8C%87%E5%8D%97%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-Map%E5%AD%97%E5%85%B8/ 

 

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|学习笔记

GMT+8, 2024-10-8 11:58 , Processed in 0.027030 second(s), 14 queries , APCu On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表