映射

映射。一个映射是通过键来访问每一个值的集合。键是一个简单的方式来从映射中找出数据。就像一个整齐标记的文件夹,而不是乱糟糟的堆叠。

相对于数组和切片只能使用整型数字作为索引,映射可以使用任意类型的键(只要这个类型可以使用==来比较)。那包括数字、字符串和其他。所有的值只能是相同的类型,所有的键也需要是相同的类型,但是键和值的类型不必相同。

为了声明一个保存映射的变量,请输入一个map关键字,后面跟着一对包含键类型的方括号([])。然后在方括号后面提供值的类型。

与切片一样,声明一个映射变量并不会自动创建一个映射,你需要调用make函数(与你创建切片相同的函数)。你可以传递给make你想要创建的映射类型(与你需要赋值到的类型相同)。

package main
import "fmt"
func main() {
	var ma map[string]string=make(map[string]string)
	mb:=make(map[string]string)
	fmt.Printf("%#v\n",ma)
	fmt.Printf("%#v\n",mb)
}

image-20201029094418558


映射字面量

就像切片和数组一样,如果预先知道映射的键和值,你可以使用字面量来创建映射。映射字面量以映射类型(以“映射[键类型]值类型”的形式)开始。后面跟着花括号,内含你想要映射初始就包含的键/值对。对于每一个键/值对,包含一个键、一个冒号和值。多个键/值对之间以逗号分隔。

package main
import "fmt"
func main() {
	mb:=map[string]string{"a":"1","b":"2"}
	mb["c"]="3"
	mb["d"]="4"
	fmt.Printf("%#v\n",mb)
}

image-20201029094953469


映射中的零值

对于数组和切片,如果你访问一个没有赋值过的键,你会得到一个零值。

根据值的类型不同,零值可能不一定是0。例如映射的值类型是string,零值就是空字符串。

package main
import "fmt"
func main() {
	mb:=map[string]string{"a":"1","b":"2"}
	mb["c"]="3"
	mb["d"]="4"
	fmt.Printf("%#v\n",mb["e"])
}

image-20201029114001915


映射变量的零值是nil

就像跟切片一样,映射变量的零值是nil。如果你声明了一个映射变量但是未赋值,它的值是nil。那意味着没有映射存在来增加键或者值。如果你尝试这么做,会产生一个panic:

package main
import "fmt"
func main() {
  var mb map[string]string;
  mb["c"]="3"
  mb["d"]="4"
  fmt.Printf("%#v\n",mb["e"])
}

image-20201029114247559

  • 在增加一个新的键/值对之前,需要使用make或者映射字面量来创建一个映射,并且赋值给映射变量。

如何区分已经赋值的值和零值

为了解决这个问题,访问映射键的时候可选地获取第2个布尔类型的值。如果这个键已经被赋过值,那么返回true,否则返回false。大多数Go开发者会将这个布尔值赋给一个名为ok的变量(因为名字简短有效)。

package main
import "fmt"
func main() {
	mb:=map[string]string{"a":"1","b":"2"}
	mb["c"]="3"
	mb["d"]=""
	v, ok := mb["d"]
	fmt.Printf("%#v,%#v\n",v,ok)
	v, ok = mb["e"]
	fmt.Printf("%#v,%#v",v,ok)
}

image-20201029115001389


使用“delete”函数删除键/值对

在分配了值之后的某个时候,你希望将它从你的映射中移除。Go提供了内建的delete函数。只需要传递给delete两个参数:你希望删除数据的映射和你希望删除的键。然后键和它关联的值都会被删除。

package main
import "fmt"
func main() {
	mb:=map[string]string{"a":"1","b":"2"}
	mb["c"]="3"
	mb["d"]=""
	v, ok := mb["c"]
	fmt.Printf("%#v,%#v\n",v,ok)
	delete(mb,"c")
	v, ok = mb["c"]
	fmt.Printf("%#v,%#v",v,ok)
}

image-20201029115143727


对映射进行for…range循环

package main
func main() {
	mb:=map[string]string{"a":"1","b":"2"}
	mb["c"]="3"
	mb["d"]=""
	for s, s2 := range mb {
		println(s,s2)
	}
}

image-20201029115326879

  • for…range以随机的顺序遍历映射的键和值,因为映射是一个非有序的键/值对集合。当你使用for…range遍历一个映射时,你无法知道你获取的是何种顺序。有时这样可以,但当需要按照特定的顺序遍历时,你需要自己写一些代码。


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!

struct 上一篇
切片 下一篇