Go map 映射/字典

发布时间: 更新时间: 总字数:1122 阅读时间:3m 作者: IP上海 分享 网址

Golang中使用Map来存储一系列的key/value键值对,可以使用key来对value进行操作(增、删、改、查),map的零值为nil。

介绍

Mapkey 只能为可使用 == 运算符的值类型(字符串、数字、bool、数组),value 可以为任何类型。

说明:

  • key 需要支持等值运算
  • map是无序的,每次遍历的顺序可能都不一样
    • 源码:runtime/map.go
    • 源码通过 fastrand 生成随机数,选择一个桶位置作为起始bucket进行遍历迭代
    • bucket 编译好,开始遍历 overflow buckets
  • 相关函数
    • 获取长度:len()
    • 删除元素:delete()
  • map 的负载因子是 6.5,平衡时间和空间,参考
    • 负载因子(load factor),用于衡量当前哈希表中空间占用率的核心指标
    • 当 B(bucket)平均每个存储的元素大于或等于 6.5 时,就会触发扩容行为
    • Java HashMap 的负载因子为何默认是 0.75
  • map 的扩缩容的主要区别在于 hmap.B 的容量大小改变
  • map 删除元素时不释放内存空间,可以通过创建一个新的 map 并从旧的 map 中复制元素
  • map 是线程不安全的,sync.Map 是线程安全的
  • map 可以使用 reflect.DeepEqual 比较
  • 读取方式,原型包括 mapaccess1/mapaccess2/mapaccess1_xxx/mapaccess2_xxx,使用:
v := m[i]
v, ok := m[i]

示例

基础使用

package main

import (
	"fmt"
)

func ExampleMap() {
	// 声明
	var ages map[string]int
	fmt.Printf("%T %#v\n", ages, ages)
	fmt.Println(ages == nil) // 默认值为 nil

	// 字面值
	// ages = map[string]int{} // 定义空map
	ages = map[string]int{"xiaowang": 18} // 定义空map
	ages["xiaoming"] = 23
	fmt.Printf("%T %#v\n", ages, ages)

	//ages = make(map[string]int)
	//fmt.Printf("%T %#v\n", ages, ages) //map[string]int map[string]int{}

	// 操作
	fmt.Println(ages["xiaoming"])
	fmt.Println(ages["xianbin"]) // 不存在该值,默认为 int 的零值 0
	// 查
	age, ok := ages["xianbin"] // 判断是否存在,返回两个值,如存在获取 age, true,不存在 0, false
	if ok {
		fmt.Println(age)
	} else {
		fmt.Println("not exist")
	}

	if age, ok := ages["xianbin"]; ok {
		fmt.Println(age)
	} else {
		fmt.Println("not exist")
	}

	// 改
	ages["xiaoming"] = 22
	// 增
	ages["xianbin"] = 18
	fmt.Printf("%T %#v\n", ages, ages)

	// 删除
	delete(ages, "xianbin")
	delete(ages, "bin") // 删除key不存在的值
	fmt.Printf("%T %#v\n", ages, ages)

	// 获取长度
	fmt.Println(len(ages))

	// 遍历数组
	delete(ages, "xiaoming")
	for k, v := range ages {
		fmt.Println(k, v)
	}

	// Output:
	//map[string]int map[string]int(nil)
	//true
	//map[string]int map[string]int{"xiaoming":23, "xiaowang":18}
	//23
	//0
	//not exist
	//not exist
	//map[string]int map[string]int{"xianbin":18, "xiaoming":22, "xiaowang":18}
	//map[string]int map[string]int{"xiaoming":22, "xiaowang":18}
	//2
	//xiaowang 18
}

func main() {
	ExampleMap()
}

说明:

  • range map 获取值的情况:
    • 获取key, value:k, v := range map
    • 仅获取key:k := range map
  • 初始化如 {"url": ["seo1", "seo2"]} 格式 map:map[string][]string{}

复合使用

package main

import (
	"fmt"
)

func ExampleMap() {
	// 声明
	var ages map[string]int
	fmt.Printf("%T %#v\n", ages, ages)
	fmt.Println(ages == nil) // 默认值为 nil

	// 字面值
	// ages = map[string]int{} // 定义空map
	ages = map[string]int{"xiaowang": 18} // 定义空map
	ages["xiaoming"] = 23
	fmt.Printf("%T %#v\n", ages, ages)

	//ages = make(map[string]int)
	//fmt.Printf("%T %#v\n", ages, ages) //map[string]int map[string]int{}

	// 操作
	fmt.Println(ages["xiaoming"])
	fmt.Println(ages["xianbin"]) // 不存在该值,默认为 int 的零值 0
	// 查
	age, ok := ages["xianbin"] // 判断是否存在,返回两个值,如存在获取 age, true,不存在 0, false
	if ok {
		fmt.Println(age)
	} else {
		fmt.Println("not exist")
	}

	if age, ok := ages["xianbin"]; ok {
		fmt.Println(age)
	} else {
		fmt.Println("not exist")
	}

	// 改
	ages["xiaoming"] = 22
	// 增
	ages["xianbin"] = 18
	fmt.Printf("%T %#v\n", ages, ages)

	// 删除
	delete(ages, "xianbin")
	delete(ages, "bin") // 删除key不存在的值
	fmt.Printf("%T %#v\n", ages, ages)

	// 获取长度
	fmt.Println(len(ages))

	// 遍历数组
	delete(ages, "xiaoming")
	for k, v := range ages {
		fmt.Println(k, v)
	}

	// Output:
	//map[string]int map[string]int(nil)
	//true
	//map[string]int map[string]int{"xiaoming":23, "xiaowang":18}
	//23
	//0
	//not exist
	//not exist
	//map[string]int map[string]int{"xianbin":18, "xiaoming":22, "xiaowang":18}
	//map[string]int map[string]int{"xiaoming":22, "xiaowang":18}
	//2
	//xiaowang 18
}

func main() {
	ExampleMap()
}

合并

package main

import (
	"fmt"

	"golang.org/x/exp/maps"
)

func main() {
	ages1 := map[string]int{"xiaowang": 18}
	ages2 := map[string]int{"xiaoming": 19}

	// Print the map before merging
	fmt.Println("The age1 Map: ", ages1)
	fmt.Println("The age2 Map: ", ages2)

	maps.Copy(ages1, ages2)
	fmt.Println("The merged Map is: ", ages1)
}
Home Archives Categories Tags Statistics
本文总阅读量 次 本站总访问量 次 本站总访客数