网络人

GO语言学习笔记6:映射(map)集合关联数组详解

Kwok: 2020-10-02 10:10:58 点击:15 评论: 0

Map 最重要的特点是通过 key 来快速检索数据,key 类似于索引,指向数据的值。map是key-value数组结构,在PHP里称为索引数组,只不过GO语言的map更强大,Key和value的值可以是多种类型,如bool,string,指针,channel等,可以将数组的[0],[1],[2]语义化为[one],[tow],[three],为了区别数组与map,GO语言在定义map时需要使用map关键字。

一、map的声明 var map 变量名 map [keytype] valuetype

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.neter8.com"     //空间“url”存上“www.neter8.com”
fmt.Println(myMap)                  //map[name:网络人 url:www.neter8.com]

map声明后不会分配内存空间,无序排列,每次打印结果顺序都可能不一样!

make内置函数用于分配并初始化类型为切片(slice)、映射(map)、或通道(channel)的对象,其第1个实参为类型,而非值,make返回类型与其参数相同。map初始分配的创建取决于size,产生的映射长度为0,size可以省略,这种情况下就会分配1个小的起始大小。

二、map的各种声明方式:

除了上面的声明方式,我们还可以有以下几种,得到的效果是一样的,喜欢哪个用哪个。

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并赋值

三、map的增、删、改、查

myMap := map[string]string{"sitename": "网络人"}
myMap["url"]="www.neter8.com"//增加
myMap["url"]="http://www.neter8.com"//修改	
value,res:=myMap["url"]//map的查找,value返回找到的值,res是一个bool值,找到返回真,否则为假
fmt.Println("值为:",value,"结果为:",res)//值为: http://www.neter8.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的遍历

map的key是自己定义的,有各种类型,不像数组和切片是由数字索引,所以map只能使用for rang遍历。使用方法与切片和数组一样。 

myMap := map[string]string{"sitename": "网络人", "url": "www.neter8.com"}
	for key, value := range myMap {
		fmt.Println("Key:",key, "Value:",value)//Key: sitename Value: 网络人 Key: url Value: www.neter8.com
	}

五、统计map

和前面的slice、数组一样,使用len即可。

myMap := map[string]string{"sitename": "网络人", "url": "www.neter8.com"}
fmt.Println("myMap有:",len(myMap ),"组key-value值")//myMap有: 2 组key-value值

六、map切片

切片的详解http://www.neter8.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.neter8.com人"
}
fmt.Println(slice) //[map[sitename:网络人 url:www.neter8.com人]]

//使用append动态增加
slice = append(slice, map[string]string{"sitename": "美食圈", "url": "www.meishiq.com"})
fmt.Println(slice) //[map[sitename:网络人 url:www.neter8.com人] map[sitename:美食圈 url:www.meishiq.com]]

七、使用结构体管理map的值

type webSite struct {
	siteName string
	url      string
	age      int
}

func main() {
	site := make(map[string]webSite) //make一个map,key的类型为string,值的类型为结构体
	site["neter8"] = webSite{"网络人", "www.neter8.com", 10}
	site["meishiq"] = webSite{"美食圈", "www.meishiq.com", 8}
	fmt.Println(site)//map[meishiq:{美食圈 www.meishiq.com 8} neter8:{网络人 www.neter8.com 10}]
}

可以看到,使用结构体来管理map更直观高效。如果要访问结构体的值可以使用:site["meishiq"].url,在开发中经常使用的都是结构体。

八、map排序实现

上面有说到map是一个无序的关联数组,如果要实现对map排序就需要借助到map切片来实现。

var mySite = map[int]string{2: "www.neter8.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.neter8.com,提供站长日常...
}

map的使用细节:

map是引用类型,如果在函数里接收并修改后也会影响到原来map的值。map的会自动扩容,不像数组有固定的大小。如果map的值还是map一定要make二次,要不然会报错。

site := make(map[string]map[string]string) //make一个map,key的类型为string,值的类型为map
site["neter8"] = make(map[string]string, 2)
site["neter8"]["name"] = "网络人"
site["neter8"]["url"] = "www.neter8.com"
fmt.Println(site)//map[neter8:map[name:网络人 url:www.neter8.com]]

数组、切片、map的简单区别:

数组:定义时[5]、[...] //里面有数字或者...必须指定大小且长度不可变。

切片:定义时[]里面无内容,是一个数组或者map的引用类型。

map:定义里需要使用关键字map,使用时需要make,key可以是有意义的单词,且可以自动增长长度。

本文地址:http://m.neter8.com/go/75.html
标签:GOmap

本站推荐阅读

热门点击文章