golang map
什么是map?
Map是Go中的内置类型,它将键与值绑定到一起。可以通过键获取相应的值。
如何创建map?
可以通过将键和值的类型传递给内置函数make
来创建一个map。语法为:make(map[KeyType]ValueType)
。(译者注:map的类型表示为map[KeyType]ValueType
)例如:
personSalary:=make(map[string]int)1
上面的代码创建了一个名为personSalary
的map。其中键的类型为string,值的类型为int。
map的0值为nil。试图给一个nilmap添加元素给会导致运行时错误。因此map必须通过make
来初始化(译者注:也可以使用速记声明来创建map,见下文)。
packagemain import( "fmt" ) funcmain(){ varpersonSalarymap[string]int ifpersonSalary==nil{ fmt.Println("mapisnil.Goingtomakeone.") personSalary=make(map[string]int) } }12345678910111213
上面的程序中,personSalary
为nil,因此使用make
初始化它。程序的输出为:mapisnil.Goingtomakeone.
向map中插入元素
插入元素给map的语法与数组相似。下面的代码插入一些新的元素给mappersonSalary
。
packagemain import( "fmt" ) funcmain(){ personSalary:=make(map[string]int) personSalary["steve"]=12000 personSalary["jamie"]=15000 personSalary["mike"]=9000 fmt.Println("personSalarymapcontents:",personSalary) }12345678910111213
上面的程序输出:personSalarymapcontents:map[steve:12000jamie:15000mike:9000]
。
也可以在声明时初始化一个数组:
packagemain import( "fmt" ) funcmain(){ personSalary:=map[string]int{ "steve":12000, "jamie":15000, } personSalary["mike"]=9000 fmt.Println("personSalarymapcontents:",personSalary) }1234567891011121314
上面的程序在声明personSalary
的同时向其中插入了两个元素。接着插入了一个以"mike"
为键的元素。程序的输出为:
personSalarymapcontents:map[steve:12000jamie:15000mike:9000]1
string
并不是可以作为键的唯一类型,其他所有可以比较的类型,比如,布尔类型,整型,浮点型,复数类型都可以作为键。如果你想了解更多关于可比较类型的话,请参阅:http://golang.org/ref/spec#Comparison_operators
访问map中的元素
现在我们已经添加了一些元素给map,现在让我们学习如何从map中提取它们。根据键获取值的语法为:map[key]
,例如:
packagemain import( "fmt" ) funcmain(){ personSalary:=map[string]int{ "steve":12000, "jamie":15000, } personSalary["mike"]=9000 employee:="jamie" fmt.Println("Salaryof",employee,"is",personSalary[employee]) }123456789101112131415
上面的程序非常简单。员工jamie
的工资被取出并打印。程序的输出为:Salaryofjamieis15000
。
如果一个键不存在会发生什么?map会返回值类型的0值。比如如果访问了personSalary
中的不存在的键,那么将返回int的0值,也就是0。
packagemain import( "fmt" ) funcmain(){ personSalary:=map[string]int{ "steve":12000, "jamie":15000, } personSalary["mike"]=9000 employee:="jamie" fmt.Println("Salaryof",employee,"is",personSalary[employee]) fmt.Println("Salaryofjoeis",personSalary["joe"]) }12345678910111213141516
上面的程序输出为:
Salaryofjamieis15000
Salaryofjoeis012
上面的程序返回joe
的工资为0。我们没有得到任何运行时错误说明键joe
在personSalary
中不存在。
我们如何检测一个键是否存在于一个map中呢?可以使用下面的语法:
value,ok:=map[key]1
上面的语法可以检测一个特定的键是否存在于map中。如果ok
是true,则键存在,value被赋值为对应的值。如果ok
为false,则表示键不存在。
packagemain import( "fmt" ) funcmain(){ personSalary:=map[string]int{ "steve":12000, "jamie":15000, } personSalary["mike"]=9000 newEmp:="joe" value,ok:=personSalary[newEmp] ifok==true{ fmt.Println("Salaryof",newEmp,"is",value) }else{ fmt.Println(newEmp,"notfound") } }123456789101112131415161718192021
在上面的程序中,第15行,ok
应该为false因为joe
不存在。因此程序的输出为:
joenotfound1
rangefor可用于遍历map中所有的元素(译者注:这里range操作符会返回map的键和值)。
packagemain import( "fmt" ) funcmain(){ personSalary:=map[string]int{ "steve":12000, "jamie":15000, } personSalary["mike"]=9000 fmt.Println("Allitemsofamap") forkey,value:=rangepersonSalary{ fmt.Printf("personSalary[%s]=%d\n",key,value) } }123456789101112131415161718
上面的程序输出如下:
Allitemsofamap
personSalary[mike]=9000
personSalary[steve]=12000
personSalary[jamie]=150001234
值得注意的是,因为map是无序的,因此对于程序的每次执行,不能保证使用rangefor遍历map的顺序总是一致的。
删除元素
delete(map,key)
用于删除map中的key。delete
函数没有返回值。
packagemain import( "fmt" ) funcmain(){ personSalary:=map[string]int{ "steve":12000, "jamie":15000, } personSalary["mike"]=9000 fmt.Println("mapbeforedeletion",personSalary) delete(personSalary,"steve") fmt.Println("mapafterdeletion",personSalary) }1234567891011121314151617
上面的程序删除以steve
为键的元素。程序输出为:
mapbeforedeletionmap[steve:12000jamie:15000mike:9000]
mapafterdeletionmap[mike:9000jamie:15000]12
map的大小
用内置函数len获取map的大小:
packagemain import( "fmt" ) funcmain(){ personSalary:=map[string]int{ "steve":12000, "jamie":15000, } personSalary["mike"]=9000 fmt.Println("lengthis",len(personSalary)) }123456789101112131415
上面程序中,len(personSalary)
获取personSalary
的大小。上面的程序输出:lengthis3
。
map是引用类型
与切片一样,map是引用类型。当一个map赋值给一个新的变量,它们都指向同一个内部数据结构。因此改变其中一个也会反映到另一个:
packagemain import( "fmt" ) funcmain(){ personSalary:=map[string]int{ "steve":12000, "jamie":15000, } personSalary["mike"]=9000 fmt.Println("Originalpersonsalary",personSalary) newPersonSalary:=personSalary newPersonSalary["mike"]=18000 fmt.Println("Personsalarychanged",personSalary) }1234567891011121314151617
上面的程序中,第14行,personSalary
赋值给newPersonSalary
。下一行,将newPersonSalary
中mike
的工资改为18000
。那么在personSalary
中mike
的工资也将变为18000
。程序的输出如下:
Originalpersonsalarymap[steve:12000jamie:15000mike:9000]
Personsalarychangedmap[jamie:15000mike:18000steve:12000]12
将map作为参数传递给函数也是一样的。在函数中对map的任何修改都会影响在调用函数中看到。
比较map
map不能通过==
操作符比较是否相等。==
操作符只能用来检测map是否为nil。
packagemain funcmain(){ map1:=map[string]int{ "one":1, "two":2, } map2:=map1 ifmap1==map2{ } }12345678910111213
上面的程序将会报错:invalidoperation:map1==map2(mapcanonlybecomparedtonil)。
比较两个map是否相等的方式是一一比较它们的元素是否相等。我会鼓励你为此编写一个程序,使其工作:)
原文链接: