【Go】(六)Go基础 -- Map

Map

  • Map是一个拥有key value对的元素的无序集合,key的值是唯一的
  • Go里面的Map就是Hash Table的引用,是引用类型,类似Pointer和Slice

一、声明和初始化

// 这样初始化默认是一个nil类型,没有引用任何散列表
var m map[string]int

fmt.Println(m == nil) // true

// 这样赋值就会出错
m["a"] = 1

// 初始化的时候,使用make
m = make(map[string]int)
fmt.Println(m == nil) // false

// 这种方式跟make的效果一样
m := map[string]int{}

// 可以初始化有默认值的map
commits := map[string]int{
    "rsc": 3711,
    "r":   2138,
    "gri": 1908,
    "adg": 912,
}

  • map的key需要是同一数据类型,map的value也需要是同一数据类型
  • Key是任何可比较类型的值(就是指可以用 == != < > <= >= 这些符号进行比较的值)
    • boolean, numeric, string
    • pointer,
    • channel,
    • interface types
    • structs or arrays that contain only those types.
  • Key类型不可以是以下的值
    • map
    • list
    • slices
    • functions
  • Value是任何类型的值

二、使用

2.1.基本使用

// set and get
m["a"] = 66
i := m["a"]

// 如果key不存在,则返回value所属类型的默认值
// 比如int就是0, string就是空字符串
// 以下j == 0
j := m["b"]

// move entry, delete成功或者失败都不返回任何值
delete(m, "b")

// 获取map的长度
n := len(m)

// 测试一个key是否存在
// 如果不存在,i==0,ok==false
i, ok := m["b"]
// 仅仅检测key有没有,使用如下方式
_, ok := m["b"]


// 迭代
for key, value := range m {
    fmt.Println("Key:", key, "Value:", value)
}


// 编译错误,map元素不是一个变量,不能取地址
// 原因是map的增长可能会导致已有的元素被重新散列到新的存储位置,这样地址就会变
_ = &m["a"] 


2.2.顺序迭代

map的迭代是无序的,如果需要顺序迭代,要自己实现

import "sort"

var m map[int]string
var keys []int
for k := range m {
    keys = append(keys, k)
}
sort.Ints(keys)
for _, k := range keys {
    fmt.Println("Key:", k, "Value:", m[k])
}

因为已经确定了m的长度,所以初始化keys slice的时候,直接指定长度会更加高效

keys := make([]int, 0, len(m))

2.3.判断两个map是否相同

不能直接判断两个map是否相同,需要自己实现


func compareMapEqual (x, y map[string]int) bool {
	if len(x) != len(y):
		return false
	for k, xv := range(x){
		if yv, ok := y[k]; !ok || xv != yv{
			return false
		}
	}
	return true
}

2.4.用map实现set

https://juejin.cn/post/6844903857101733902
https://geektutu.com/post/hpg-empty-struct.html

go中没有set类型,可以借助map key唯一的特点实现

如果使用bool作为value类型,会占用1个字节,100w条数据就会多占1MB左右的空间,使用空struct就会更节约内存

unsafe.Sizeof(struct{}{})  == 0

type void struct{}
var v void

set := make(map[string]void)

// set
set["a"] = v

// get
_, ok := set["b"]

// delete
delete(set, "b")


// len
len(set)

// for loop
for k := range set{
	fmt.Println(k)
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值