清水泥沙

golang基础(16.字典类型声明,初始化,简单使用)

字典定义

go中支持字典类型的数据,所谓字典类型,指的是一个键值对的关系集合。一个键对应一个值,go中的字典是一个无序集合,不会根据键或值进行排序。在go中声明字典:

package main

import (
	"fmt"
	"strconv"
)

func main() {
	var map1 map[string]int
	fmt.Println(map1)
	map2 := map[string]int{
		"one": 1,
		"two": 2,
	}
	fmt.Println(map2)
	key := "two"
	value, ok := map2[key]
	if ok {
		fmt.Printf("map has key:" + key + " values is:" + strconv.Itoa(value))
	} else {
		fmt.Printf("map no has key")
	}
}

字典声明

var map1 map[string]int

在go中声明字典需要指定键的数据类型以及值得数据类型

字典初始化

我们可以通过先声明再初始化的方式进行初始化,就像上面示例代码做的那样,也可以通过 := 将声明和初始化合并为一条语句:

map2 := map[string]int{
		"one": 1,
		"two": 2,
}

还可以通过make函数来初始化一个字典,使用make函数创建的字典可以直接赋值。直接声明不允许这样操作,因为数据没被初始化为nil赋值会直接抛异常。

package main

func main() {
	map1 := make(map[string]int)
	map1["test"] = 1
	map1["test2"] = 2
}

也可以选择是否在创建时指定该字典的初始存储能力(超出会自动扩容):

testMap = make(map[string]int, 100)

元素赋值

直接指定key和值便可以对字典进行修改

map1["test"] = 1

字段初始化之后才能进行赋值操作,如果仅仅是声明,此时 testMap 的值为 nil,在 nil 上进行操作编译期间会报 panic(运行时恐慌),导致编译不通过。

查找元素

上面的示例代码已经显示,在字典中输入键值,可以返回两个参数,一个为键的值,第二个参数为布尔类型代表是否获取成功,如果失败第一个参数为nil。

  value, ok := map2[key]
	if ok {
		fmt.Printf("map has key:" + key + " values is:" + strconv.Itoa(value))
	} else {
		fmt.Printf("map no has key")
	}

:::warning 需要注意的是,go的字典内部是通过hash表来实现的。当用户设置键值时,首先会将键转换为一个hash值进行存储。而在查找时也会将键转换为hash值在hash表中进行查询,从而提交查找性能。但是hash会存在hash冲突,即不同的键也会产生同样的hash值,这个时候 Go 底层还会判断原始键的值和类型是否相等。也正因如此,我们在声明字典的键类型时,要求数据类型必须是支持通过 == 或 != 进行判等操作的类型,比如数字类型、字符串类型、数组类型、结构体类型等,不过为了提高字典查询性能,类型长度越短约好,通常,我们会将其设置为整型或者长度较短的字符串类型。 :::

删除元素

Go 语言提供了一个内置函数 delete(),用于删除容器内的元素,我们可以通过这个函数来实现字典元素的删除:

package main

import "fmt"

func main() {
	map1 := make(map[string]int)
	map1["test"] = 1
	map1["test2"] = 2
	fmt.Println(map1)
	delete(map1, "test")
	fmt.Println(map1)
}

:::warning 这个键不存在或者字典尚未初始化,这个调用也不会有什么副作用。 :::