映射
go语言里的映射是一种用来存储key,value关系的数据结构。其实就是我们在其他语言中常用的map。
映射的创建
使用make函数声明并创建一个映射
m := make(map[string]int)
上面的代码表示创建一个映射,键的类型为string,值的类型为int。上面我们使用make函数用来创建了一个切片,在之前的文章中,切片也可以通过make函数来创建。
package main
import (
"fmt"
)
func main(){
m := map[string]int{"one":1,"two":2}
fmt.Println(m)
}
//map[one:1 two:2]
上面的代码使用字面量的形式创建了一个映射。里面包括两个元素。
使用映射
package main
import (
"strconv"
"fmt"
)
func main(){
//创建一个空映射
m := map[string]int{}
//往映射中添加数据
for i:=0 ; i<10 ; i++{
m["key-" + strconv.FormatInt(int64(i),10)] = i
}
fmt.Println(m)
}
//map[key-7:7 key-0:0 key-1:1 key-2:2 key-4:4 key-6:6 key-3:3 key-5:5
//key-8:8 key-9:9]
上面的代码,向映射中添加了10个元素。strconv.FormatInt(int64(i),10)这句代码的意思是将i先转换为int64的数据类型,然后再将其结果转换为string类型。 strconv.FormatInt(i int64,base int)函数有两个参数,第一个参数的类型为int64,第二个参数的类型为一个int类型的数字,范围在2 <= base <= 36。表示进制。
关于FormatInt的更多知识,请点这里
然后我们来看下,上面代码输出的结果,会发现在输出的结果中,元素的顺序并没有安装存入的顺序输出,这就证明了映射中的数据存储是无序的。
package main
import (
"fmt"
)
func main(){
//声明,但是未初始化映射
var m map[string]int
//此时对映射操作会报错
m["one"] = 1
fmt.Println(m)
}
//panic: assignment to entry in nil map
package main
import (
"fmt"
)
func main(){
//声明,但是未初始化映射
m := map[string]int{"one":1,"two":2}
//获取映射中的元素
var value = m["one"]
fmt.Println(value);
}
//1
上面的代码,获取映射中键为one的值。那么如果获取的键的值不存在呢?看下面的代码:
package main
import (
"fmt"
)
func main(){
//声明,但是未初始化映射
m := map[string]int{"one":1,"two":2}
//获取映射中的元素
var value = m["three"]
fmt.Println(value);
}
//0
上面获取一个不存在的键值的时候,会返回值的类型的默认值。在之前的文章中我们提到过,int类型对象的默认值为0。这样在程序中使用的时候,我们需要判断返回的值是否为默认值来确定元素是否存在于映射中。在go语言中,我们获取映射值的时候,可以指定第二个接收变量,这个变来用来表示对应键值的元素是否存在,看下面的代码:
package main
import (
"fmt"
)
func main(){
//声明,但是未初始化映射
m := map[string]int{"one":1,"two":2}
//获取映射中的元素
var value , exists = m["three"]
if(exists){
fmt.Println(value);
}
var value2 , exists2 = m["one"]
if(exists2){
fmt.Println(value2);
}
}
//1
由于键值为three的元素在映射中不存在,所以上面的结果会输出1。
删除
package main
import (
"fmt"
)
func main(){
//声明,但是未初始化映射
m := map[string]int{"one":1,"two":2}
delete(m,"two")
fmt.Println(m)
}
//map[one:1]
使用delete函数来删除映射中,指定键值的元素。如果指定的键值不存在,会怎么样?看下面的代码:
package main
import (
"fmt"
)
func main(){
//声明,但是未初始化映射
m := map[string]int{"one":1,"two":2}
delete(m,"two1")
fmt.Println(m)
}
//map[one:1 two:2]
也就是说,如果指定删除的键值不存在,delete操作没有任何行为。
映射的遍历
使用range遍历:
package main
import (
"fmt"
)
func main(){
//声明,但是未初始化映射
m := map[string]int{"one":1,"two":2}
for key , value := range m{
fmt.Println(key,"=",value);
}
}
//one = 1
//two = 2
如果只想获取映射中所有的key值,可以这样:
package main
import (
"fmt"
)
func main(){
//声明,但是未初始化映射
m := map[string]int{"one":1,"two":2}
//初始化一个切片用来保存所有的key
keys := []string{}
//遍历映射获取所有的key,并将key添加到切片keys中
for key := range m{
keys = append(keys,key)
}
fmt.Println(keys);
}
//[one two]
如果只是想获取所有的值,可以这样做:
package main
import (
"fmt"
)
func main(){
//声明,但是未初始化映射
m := map[string]int{"one":1,"two":2}
//初始化一个切片用来保存所有的value
values := []int{}
//遍历映射获取所有的value,并将key添加到切片values中
for _ , value := range m{
values = append(values,value)
}
fmt.Println(values);
}
//[1 2]
上面的循环中,for 语句的第一个参数使用了_来代替。在go语言中,_表示占位符,因为我们需要的是第二个接收参数,所以第一个接收参数我们可以使用占位符来代替。