无所不能的映射 | Go 主题月

479 阅读4分钟

一个没有感情的茶缸机器又来了,在这假期的第一天,我在家学习Go,同时也产出这一篇文章,好了,废话不多说,让我们开始聊聊今天的话题——映射,一切为了大茶缸

前言

映射,顾名思义,就是通过某一个点,可以快速找到另一个东西的意思,也就是通过一个Key,可以快速的找到另一个value,而在Go中,这样的一个东西就是一种数据类型——Map.

Map与数组和切片不相同的地方在于,Map的健不单单只是一个数字,它可以是任何的数据类型,所以,它的使用也特别的自由。

声明一个Map

想要声明一个Map,首先必须指定这个Map的键和值是什么类型

    a := map[string]int{
            "test":1,
            "haha":2,
    }

同样的,它也可以跟切片一样,通过make的方式来完成预分配,这里的make同样接受一个或者两个参数,一个是这个Map的数据类型,一个是这个Map的容量大小。

    ints := make(map[string]int) 
    
    i := make(map[string]int, 3)

在通过make出来的Map,在初始的时候,长度都是为0。

注意一些小细节

下载.jpg

访问一个不存在的键

如果我们去访问一个在Map中不存在的键的时候会发生什么事呢

    a := map[string]int{
            "test": 1,
    }
    fmt.Print(a["test"]) //1
    fmt.Print(a["hahah"]) //0

当我们访问一个不存在的键的时候,它会返回一个相应的零值作为结果(这里的返回结果类型是Int)。

所以为了可以知道我们访问的这个键是不是存在的,访问的时候,提供了第二个参数。

    a := map[string]int{
            "test": 1,
    }
    if i,ok := a["test"]; ok {
            fmt.Print(i)
    }

这第二个参数ok就告诉了我们,你所访问的这个键是否存在于这个映射Map中,它是一个布尔值,如果存在的话,它就为true,反之则是false。

Map不会被复制

我们知道,在传递一个数组的时候,它会被进行复制,但是Map不会,在传递过程中,它们会共享一个共同的底层数据。

也就是说,如果对其中一个进行更改,那么另一个也会随着改变

func changeMap(a map[string]int)  {
	for k,_ := range a{
		a[k] = 100
	}
}

func main() {
	a := map[string]int{
		"test": 1,
	}
	changeMap(a)
	fmt.Print(a) // map[test:100]
}

这里我通关range方法去迭代这个Map,把它里面的value做了更改,然后我们会看到外层传进来的Map同样也被改变了,这也就印证了一点,Map不会被复制。

Map配合切片使用

我们在使用Map的时候,同样可以配合切片来完成一些功能,例如,对切片的内容进行分组。

下面这个例子,我是把切片里面的数字,根据十位数的不同来进行分组的一个简单的例子

func group(a []int) map[float64][]int {
	ints := make(map[float64][]int)
	for _,v := range a{
		g :=  math.Trunc( float64(v) / 10) * 10
		ints[g] = append(ints[g],v)
	}
	return ints
}

func main() {
	a := []int {11,12,22,23,33,34,44,45}
	ints := group(a)
	fmt.Print(ints) 
        // map[10:[11 12] 20:[22 23] 30:[33 34] 40:[44 45]]
}

除了可以对切片进行分组这样的小功能以外,我们知道,很多语言里面存在一个数据结构,那就是集合,而在集合里面是有一个去重和排序的功能的。

例如,在javascript里面,如果我们要对一个数组进行去重的工作,可以通过把这个数组放到一个集合里面去,来完成去重的工作,但是在Go里面,却没有集合的这一个数据结构,但是我们同样可以通过切片和映射配合的方式来完成对一个切片进行去重的工作。

func set(a []int) []int {
	ints := make(map[int]bool)
	list := make([]int,len(ints))
	for _,v := range a{
		ints[v] = true
	}
	for k,v := range ints {
		if v == true {
			list = append(list, k)
		}
	}
	return list
}

func main() {
	a := []int {11,11,22,22,33,33,44,33}
	ints := set(a)
	fmt.Print(ints)
        // [11 22 33 44]

通过上面两个简单的例子,我们可以看到Map的无所不能,它可以完成很多意想不到的工作。

最后

作为一个正经的茶缸机器,实在是想不到怎么收尾,那就这样把.....

祝各位看官大人节日愉快,我要出门去浪了。

FkVc89dAwq_small.jpg