Map 最重要的特点是通过 key 来快速检索数据,key 类似于索引,指向数据的值。map是key-value数组结构,在PHP里称为索引数组,只不过GO语言的map更强大,Key和value的值可以是多种类型,如bool,string,指针,channel等,可以将数组的[0],[1],[2]语义化为[one],[tow],[three],为了区别数组与map,GO语言在定义map时需要使用map关键字。
var myMap map[string]string //定义一个myMap索引值为string类型,值也是string类型,实体myMap["name"]="网络人"
myMap = make(map[string]string) //不写size的情况只分配1个key-value的空间
myMap["name"] = "网络人" //空间“name”存上“网络人”
myMap["url"] = "www.55mx.com" //空间“url”存上“www.55mx.com”
fmt.Println(myMap) //map[name:网络人 url:www.55mx.com]
map声明后不会分配内存空间,初始化需要使用make来分配内存才能赋值和使用。GO语言里的 map是无序排列,每次打印结果顺序都可能不一样!
make内置函数用于分配并初始化类型为切片(slice)、映射(map)、或通道(channel)的对象,其第1个实参为类型,而非值,make返回类型与其参数相同。map初始分配的创建取决于size,产生的映射长度为0,size可以省略,这种情况下就会分配1个小的起始大小。
除了上面的声明方式,我们还可以有以下几种,得到的效果是一样的,喜欢哪个用哪个。
var myMap map[string]string //定义一个nil值的map,因为没有make哦~
var myMap = make(map[string]string)//声明就直接make,这就可以使用了哦~
var myMap map[string]string = map[string]string{"sitename":"网络人"}//声明并赋值,底层自动make
var myMap = map[string]string{"sitename": "网络人"} //var推导类型,上面简写。
myMap := map[string]string{"sitename":"网络人"}//使用类型自动推导声明map并赋值
myMap := map[string]string{"sitename": "网络人"}
myMap["url"]="www.55mx.com"//增加
myMap["url"]="http://www.55mx.com"//修改
value,res:=myMap["url"]//map的查找,value返回找到的值,res是一个bool值,找到返回真,否则为假
fmt.Println("值为:",value,"结果为:",res)//值为: http://www.55mx.com 结果为: true
delete(myMap,"url")//删除,如果指定的值不存在,不会报错
value,res =myMap["url"]//再次查找url
fmt.Println("值为:",value,"结果为:",res)//值为: 结果为: false
如果要一次性删除所有的KEY,可以使用遍历逐个删除,也可以使用make重新分配一个内存空间,原来的内存空间会被系统回收。效率更高。
上面通过value,res:=myMap["url"]完成对url是否存在的查找,如果有存在返回true,我们只需要判断res就可以了。
map的key是自己定义的,有各种类型,不像数组和切片是由数字索引,所以map只能使用for rang遍历。使用方法与切片和数组一样。
myMap := map[string]string{"sitename": "网络人", "url": "www.55mx.com"}
for key, value := range myMap {
fmt.Println("Key:",key, "Value:",value)//Key: sitename Value: 网络人 Key: url Value: www.55mx.com
}
和前面的slice、数组一样,使用len即可。
myMap := map[string]string{"sitename": "网络人", "url": "www.55mx.com"}
fmt.Println("myMap有:",len(myMap ),"组key-value值")//myMap有: 2 组key-value值
切片的详解http://www.55mx.com/go/74.html:如果切片的数据类型是map,则map个数就可以动态变化了。
var slice []map[string]string //定义一个map的切片
slice = make([]map[string]string, 1) //make后给1个空间
if slice[0] == nil {
slice[0] = make(map[string]string, 2)
slice[0]["sitename"] = "网络人"
slice[0]["url"] = "www.55mx.com人"
}
fmt.Println(slice) //[map[sitename:网络人 url:www.55mx.com人]]
//使用append动态增加
slice = append(slice, map[string]string{"sitename": "美食圈", "url": "www.meishiq.com"})
fmt.Println(slice) //[map[sitename:网络人 url:www.55mx.com人] map[sitename:美食圈 url:www.meishiq.com]]
type webSite struct {
siteName string
url string
age int
}
func main() {
site := make(map[string]webSite) //make一个map,key的类型为string,值的类型为结构体
site["55mx"] = webSite{"网络人", "www.55mx.com", 10}
site["meishiq"] = webSite{"美食圈", "www.meishiq.com", 8}
fmt.Println(site)//map[meishiq:{美食圈 www.meishiq.com 8} 55mx:{网络人 www.55mx.com 10}]
}
可以看到,使用结构体来管理map更直观高效。如果要访问结构体的值可以使用:site["meishiq"].url,在开发中经常使用的都是结构体。
八、map排序实现
上面有说到map是一个无序的关联数组,如果要实现对map排序就需要借助到map切片来实现。
var mySite = map[int]string{2: "www.55mx.com", 3: "网络人", 1: "提供站长日常问题的解决方法分享等。"} //声明map,key为int,value为string
//要求,我们要按key值由高到底排序,即:3、2、1
var mapSotr []int //定义一个切片
for k, _ := range mySite {
mapSotr = append(mapSotr, k) //将key追加给mapSotr
}
sort.Sort(sort.Reverse(sort.IntSlice(mapSotr))) //使用sort包里多个函数倒序
//如果需要从1-3方式排序,我们只需要1个sotr.Ints(mapSotr)函数即可完成
fmt.Println(mapSotr) //[3 2 1]
for _, v := range mapSotr {
fmt.Println(mySite[v]) //网络人,www.55mx.com,提供站长日常...
}
map是引用类型,如果在函数里接收并修改后也会影响到原来map的值。map的会自动扩容,不像数组有固定的大小。如果map的值还是map一定要make二次,要不然会报错。
site := make(map[string]map[string]string) //make一个map,key的类型为string,值的类型为map
site["55mx"] = make(map[string]string, 2)
site["55mx"]["name"] = "网络人"
site["55mx"]["url"] = "www.55mx.com"
fmt.Println(site)//map[55mx:map[name:网络人 url:www.55mx.com]]
数组、切片、map的简单区别:
数组:定义时[5]、[...] //里面有数字或者...必须指定大小且长度不可变。
切片:定义时[]里面无内容,是一个数组或者map的引用类型。
map:定义里需要使用关键字map,使用时需要make,key可以是有意义的单词,且可以自动增长长度。
除非注明,网络人的文章均为原创,转载请以链接形式标明本文地址:https://www.55mx.com/post/75
《GO语言学习笔记6:映射(map)集合关联数组详解》的网友评论(0)