目录
  • 一、Map 的定义
    • Map 的定义
    • Map 中的 Key
  • 二、Map 的操作

    一、Map 的定义

    Go 中的 Map 是一组无需的 K-V 类型的数据,与 Python 中的字典 Dict 和 Java 中的 HashMap 结构类似。未被初始化的 Map 为 nil。

    // Map 的结构
    map[string]string

    Map 的定义

    func main() {
    
       // 使用 Map 结构 函数定义 Map
       info := map[string]string{
          "name":    "Stark",
          "address": "NewYork",
       }
    
       fmt.Printf("%T, %v\n", info, info)
    
       // 使用 make 函数定义 Map
       polit := make(map[string]string)
       polit["nickname"] = "Maverick"
       polit["aircraft"] = "F18"
       fmt.Printf("%T, %v\n", polit, polit)
    
       // 定义空 Map
       maverick := map[string]string{}
       fmt.Printf("%T, %v", maverick, maverick)
    }

    执行上述代码,输出结果如下:

    map[string]string, map[address:NewYork name:Stark]
    map[string]string, map[aircraft:F18 nickname:Maverick]
    map[string]string, map[]

    Map 中的 Key

    Map 中的 Key 必须是唯一的,且 Key 必须支持 == 和 != 比较操作符。Map 中 Key 可以是 int、rune、指针和结构体等类型(支持 == 和 !=

    Go 编程复杂数据类型 Map

    切片不支持比较(切片只能和 nil 比较),不能作为 Map 的 Key,数组支持比较操作,可以作为 Key。

    func main() {
    
       structKey01 := structKey{name: "structKey01"}
       fmt.Printf("%T", structKey01)
       info := map[structKey]string{
          structKey01: "Stark",
       }
       fmt.Printf("%T, %v\n", info, info)
    
       info1 := map[interfaceKey]string{
          interfaceKey: "Stark",
       }
       fmt.Printf("%T, %v\n", info1, info1)
    }
    
    type structKey struct {
       name string
    }
    
    type interfaceKey interface {
    }

    接口和结构体可作为 Key,前提是所包含的属性必须都是可以进行 == 或者 != 比较的,如果包含一个属性不可以进行 == 或者 != 比较,便不能作为 Key。

    二、Map 的操作

    • 增加或者修改键值对
    • 查询,如果查询的键不存在返回 空字符串
    func main() {
    
       // 使用 Map 结构 函数定义 Map
       info := map[string]string{
          "name":    "Stark",
          "address": "NewYork",
       }
    
       fmt.Printf("%p, %T, %v\n", info, info, info)
    
       // 增加 KV
       info["nickname"] = "IRONMAN"
       // 修改
       info["name"] = "Tony Stark"
       fmt.Printf("%p, %T, %v\n", info, info, info)
    
       // 查询,Key 存在
       fmt.Println("名字属性值是:", info["name"])
       // 查询,Key 不存在
       fmt.Println("技能属性值是:", info["weapon"])
    
       // 添加一个空值的 KV
       info["balance"] = ""
       fmt.Println("余额属性值是:", info["balance"])
    
    }

    执行上述代码,输出结果如下:

    0xc00010e180, map[string]string, map[address:NewYork name:Stark]
    0xc00010e180, map[string]string, map[address:NewYork name:Tony Stark nickname:IRONMAN]
    名字属性值是: Tony Stark
    技能属性值是: 
    余额属性值是: 

    根据上述代码,查询时如果 Key 不存在返回空字符串,如果 Key 的值是空字符串,那么查询时返回的也是空字符串,显然通过返回字符串是否为空来判断 Key 是否存在是不准确的。

    应该如何判断 Key 是否存在?

    Map 通过 [Key] 进行取值时会有两个返回值,第一个值是 Key 对应的 Value,第二个值是布尔值,如果为 true 表示 Key 存在,否则表示 Key 不存在。

    func main() {
       // 其余代码保持不变 
       weaponVal, ok1 := info["weapon"]
       fmt.Printf("weapon 属性值是:%v, 是否存在:%v\n", weaponVal, ok1)
       balanceVal, ok2 := info["balance"]
       fmt.Printf("balance 属性值是:%v, 是否存在:%v\n", balanceVal, ok2)
    
    }

    执行上述代码,输出结果如下:

    weapon 属性值是:, 是否存在:false
    balance 属性值是:, 是否存在:true

    删除 Key 需要使用到内置的 delete 函数,在执行删除操作时,如果 Key 不存在也不会有异常

    func main() {
    
       // 其余代码保持不变 
       delete(info, "nickname")
       fmt.Printf("%p, %T, %v\n", info, info, info)
       delete(info, "weapon")
       fmt.Printf("%p, %T, %v\n", info, info, info)
    
    }

    执行上述代码,输出结果如下:

    0xc000098180, map[string]string, map[address:NewYork balance: name:Tony Stark]
    0xc000098180, map[string]string, map[address:NewYork balance: name:Tony Stark]

    遍历 Map 可以使用 for ... range

    func main() {
    
       // 使用 Map 结构 函数定义 Map
       info := map[string]string{
          "name":    "Stark",
          "address": "NewYork",
       }
    
       for k, v := range info {
          fmt.Println(k, ":", v)
       }
    
    }

    执行上述代码,输出结果如下:

    name : Tony Stark
    address : NewYork

    Map 的遍历是无序的

    声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。