设为首页 收藏本站
查看: 1133|回复: 0

[经验分享] GoLang基础数据类型

[复制链接]

尚未签到

发表于 2018-9-20 11:08:45 | 显示全部楼层 |阅读模式
  GoLang基础数据类型--->字典(map)详解
  作者:尹正杰
  版权声明:原创作品,谢绝转载!否则将追究法律责任。
   可能大家刚刚接触Golang的小伙伴都会跟我一样,这个map是干嘛的,是函数吗?学过python的小伙伴可能会想到map这个函数。其实它就是Golang中的字典。下面跟我一起看看它的特性吧。map 也就是 Python 中字典的概念,它的格式为“map[keyType]valueType”。 map 的读取和设置也类似 slice 一样,通过 key 来操作,只是 slice 的index 只能是`int`类型,而 map 多了很多类型,可以是 int ,可以是 string及所有完全定义了 == 与 != 操作的类型。
  一.map的赋值方式
  1.先的声明再初始化最后赋值
  

/*  
#!/usr/bin/env gorun
  
@author :yinzhengjie
  
Blog:http://www.cnblogs.com/yinzhengjie/tag/GO%E8%AF%AD%E8%A8%80%E7%9A%84%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
  
EMAIL:y1053419035@qq.com
  
*/
  

  
package main
  

  
import (
  
     "fmt"
  
     "reflect"
  
)
  

  
func main() {
  
     var yinzhengjie map[string]string //先声明一个字典(map)名字叫做yinzhengjie。其key所对应的数据类型是“string”[字符串],value所对应的数据类型也是“string”。
  
     fmt.Printf("判断yinzhengjie字典是否为空:【%v】\n",yinzhengjie == nil)  //声明的字典,默认为空,需要用make进行初始化操作(map是引用类型,未初始化的是指向nil,初始化了以后应该就有自己的内存空间了,所以不是nil。)所以返回值为空。
  
     fmt.Printf("第一次查看yinzhengjie字典的值:【%v】\n",yinzhengjie)
  
     yinzhengjie = make(map[string]string) //再使用make函数进行初始化创建一个非nil的map,nil map不能赋值,如果直接赋值会报错:“panic: assignment to entry in nil map”
  
     fmt.Printf("再次判断yinzhengjie字典是否为空:【%v】\n",yinzhengjie == nil) //你就把它理解为一个指针,没初始化就是nil,make之后分配内存了,一旦分配了内存地址就不为空了
  
     fmt.Printf("第二次查看yinzhengjie字典的值:【%v】\n",yinzhengjie)
  
     yinzhengjie["name"] = "尹正杰"
  
     fmt.Printf("yinzhengjie字典的类型为:【%v】\n",reflect.TypeOf(yinzhengjie))
  
     fmt.Printf("第三次查看yinzhengjie字典的值:【%v】\n",yinzhengjie)
  
}
  

  

  

  
#以上代码执行结果如下:
  
判断yinzhengjie字典是否为空:【true】
  
第一次查看yinzhengjie字典的值:【map[]】
  
再次判断yinzhengjie字典是否为空:【false】
  
第二次查看yinzhengjie字典的值:【map[]】
  
yinzhengjie字典的类型为:【map[string]string】
  
第三次查看yinzhengjie字典的值:【map[name:尹正杰]】
  

  2.直接make进行初始化之后再赋值
  

/*  
#!/usr/bin/env gorun
  
@author :yinzhengjie
  
Blog:http://www.cnblogs.com/yinzhengjie/tag/GO%E8%AF%AD%E8%A8%80%E7%9A%84%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
  
EMAIL:y1053419035@qq.com
  
*/
  

  
package main
  

  
import "fmt"
  

  
func main() {
  
     yinzhengjie := make(map[string]int) //表示创建一个key为string,value的值为int的数据类型。
  
     yinzhengjie["yzj"] = 25
  
     fmt.Println(yinzhengjie)
  
}
  

  

  

  
#以上代码执行结果如下:
  
map[yzj:25]
  

  3.直接初始化赋值
  

/*  
#!/usr/bin/env gorun
  
@author :yinzhengjie
  
Blog:http://www.cnblogs.com/yinzhengjie/tag/GO%E8%AF%AD%E8%A8%80%E7%9A%84%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
  
EMAIL:y1053419035@qq.com
  
*/
  

  
package main
  

  
import "fmt"
  

  
func main() {
  
     yinzhengjie := map[string]int{
  
         "尹正杰":18,
  
         "饼干":20,
  
     }
  
     fmt.Println(yinzhengjie)
  
}
  

  

  

  
#以上代码执行结果如下:
  
map[尹正杰:18 饼干:20]
  

  二.map的增删改查
  1.字典的赋值操作
  

/*  
#!/usr/bin/env gorun
  
@author :yinzhengjie
  
Blog:http://www.cnblogs.com/yinzhengjie/tag/GO%E8%AF%AD%E8%A8%80%E7%9A%84%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
  
EMAIL:y1053419035@qq.com
  
*/
  

  
package main
  

  
import "fmt"
  

  
func main() {
  
     yinzhengjie := make(map[int]string)
  
     letter := []string{"a","b","c","d","e","f","g","h"}
  
     for k,v := range letter{
  
         yinzhengjie[k] = v
  
     }
  
     fmt.Println(yinzhengjie) //注意,字典是无序的哟!
  
}
  

  

  

  

  
#以上代码执行结果如下:
  
map[7:h 0:a 1:b 2:c 3:d 4:e 5:f 6:g]
  

  2.字典的删除操作
  

/*  
#!/usr/bin/env gorun
  
@author :yinzhengjie
  
Blog:http://www.cnblogs.com/yinzhengjie/tag/GO%E8%AF%AD%E8%A8%80%E7%9A%84%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
  
EMAIL:y1053419035@qq.com
  
*/
  

  
package main
  

  
import "fmt"
  

  
func main() {
  
     yinzhengjie := make(map[int]string)
  
     letter := []string{"a","b","c","d","e","f","g","h"}
  
     for k,v := range letter{
  
         //fmt.Println(k,v)
  
         yinzhengjie[k] = v
  
     }
  
     fmt.Println(yinzhengjie) //注意,字典是无序的哟!
  

  
     for i:=0;i  
     NAME string
  
}
  

  
func main() {
  
     dict := make(map[int]*Student)
  
     dict[1] = &Student{

  
        >  
         NAME:"yinzhengjie",
  
     }
  

  
     dict[2] = &Student{

  
        >  
         NAME:"尹正杰",
  
     }
  

  

  
     fmt.Println(dict[1])
  
     s := dict[1]
  
     s.ID = 100000  //原地修改字典的value.
  
     fmt.Println(dict)
  
     fmt.Println(dict[1])
  
}
  

  

  

  
#以上代码执行结果如下:
  
&{100 yinzhengjie}
  
map[1:0xc042044400 2:0xc042044420]
  
&{100000 yinzhengjie}
  

  三.map的常用技巧
  1.判断map键值是否存在
  

/*  
#!/usr/bin/env gorun
  
@author :yinzhengjie
  
Blog:http://www.cnblogs.com/yinzhengjie/tag/GO%E8%AF%AD%E8%A8%80%E7%9A%84%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
  
EMAIL:y1053419035@qq.com
  
*/
  

  
package main
  

  
import "fmt"
  

  
func main() {
  
     yinzhengjie := make(map[int]string)
  
     letter := []string{"a","b","c","d","e","f","g","h"}
  
     for k,v := range letter{
  
         yinzhengjie[k] = v
  
     }
  
     fmt.Printf("字典中的值为:【%v】\n",yinzhengjie) //注意,字典是无序的哟!
  
     if v, ok := yinzhengjie[1]; ok {
  
         fmt.Println("存在key=",v)
  
     }else {
  
         fmt.Println("没有找到key=",v)
  
     }
  

  
     v ,ok := yinzhengjie[1]
  
     if ok {
  
         fmt.Println("再一次确认,已经存在key=",v)
  
     }else {
  
         fmt.Println("再一次确认,没有找到key=",v)
  
     }
  
}
  

  

  

  

  
#以上代码执行结果如下:
  
字典中的值为:【map[3:d 4:e 5:f 6:g 7:h 0:a 1:b 2:c]】
  
存在key= b
  
再一次确认,已经存在key= b
  

  2.map的排序
  我们都知道字典的默认都是无需的,但是我们可以借用标准库的包来进行基于字母或数字的顺序来排序,从而达到我们想要的结果,我们就以2016全球计算机语言排行前十的案例来展示吧:
  

/*  
#!/usr/bin/env gorun
  
@author :yinzhengjie
  
Blog:http://www.cnblogs.com/yinzhengjie/tag/GO%E8%AF%AD%E8%A8%80%E7%9A%84%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
  
EMAIL:y1053419035@qq.com
  
*/
  

  
package main
  

  
import (
  
     "fmt"
  
     "sort"
  
)
  

  
func main() {
  
     var ProgramingLanguage = map[string]int{
  
         "Java":                    0,
  
         "C":                         1,
  
         "C++":                           2,
  
         "Python":                   3,
  
         "C#":                          4,
  
         "PHP":                       5,
  
         "JavaScript":             6,
  
         "Visual Basic.NET":         7,
  
         "Perl":                       8,
  
         "Assembly language":       9,
  
         "Ruby":                      10,
  
     }
  
     var SortString []string
  
     for k := range ProgramingLanguage {
  
         SortString = append(SortString, k)
  
     }
  
     sort.Strings(SortString)  //会根据字母的顺序进行排序。
  
     for _, k := range SortString {
  
         fmt.Println("Key:", k, "Value:", ProgramingLanguage[k])
  
     }
  
}
  

  

  

  
#以上代码执行结果如下:
  
Key: Assembly language Value: 9
  
Key: C Value: 1
  
Key: C# Value: 4
  
Key: C++ Value: 2
  
Key: Java Value: 0
  
Key: JavaScript Value: 6
  
Key: PHP Value: 5
  
Key: Perl Value: 8
  
Key: Python Value: 3
  
Key: Ruby Value: 10
  
Key: Visual Basic.NET Value: 7
  

  3.map的嵌套
  

/*  
#!/usr/bin/env gorun
  
@author :yinzhengjie
  
Blog:http://www.cnblogs.com/yinzhengjie/tag/GO%E8%AF%AD%E8%A8%80%E7%9A%84%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
  
EMAIL:y1053419035@qq.com
  
*/
  

  
package main
  

  
import "fmt"
  

  
type EmployeeInformation map[string]int
  

  
func main() {
  

  
     StaffQuarters := make(map[string]EmployeeInformation)
  
     EmployeeNumber := make(EmployeeInformation)
  
     EmployeeNumber["yinzhengjie"] = 23
  
     EmployeeNumber["bingan"] = 24
  

  
     StaffQuarters["888"] = EmployeeNumber
  
     StaffQuarters["999"] = EmployeeInformation{"fanbinxin": 25, "zhouzhiruo": 26,}
  
     fmt.Println(StaffQuarters)
  
}
  

  

  

  
#以上代码执行结果如下:
  
map[888:map[bingan:24 yinzhengjie:23] 999:map[fanbinxin:25 zhouzhiruo:26]]
  

  4.map的嵌套用法展示
  

/*  
#!/usr/bin/env gorun
  
@author :yinzhengjie
  
Blog:http://www.cnblogs.com/yinzhengjie/tag/GO%E8%AF%AD%E8%A8%80%E7%9A%84%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
  
EMAIL:y1053419035@qq.com
  
*/
  

  
package main
  

  
import "fmt"
  

  
func main() {
  
     Province:=make(map[string]map[string][]string) //定义省的字典
  
     City:=make(map[string][]string)  //定义市区的字典
  
     Scenery := make(map[string][]string)  //定义景区的字典
  
     Scenery["西安"] = []string{    "秦始皇兵马俑","大雁塔","大唐芙蓉园","华清池","黄巢堡国家森林公园","西安碑林博物馆","骊山国家森林公园","西安城墙","秦始皇陵","翠华山",}
  
     Scenery["安康"] = []string{"中坝大峡谷","香溪洞","安康双龙生态旅游度假区","瀛湖生态旅游景区","简车湾休闲景区","南宫山","天书峡景区","汉江燕翔洞景区","飞渡峡-黄安坝景区","千层河",}
  
     City["西安市区"]=[]string{"新城区","碑林区","莲湖区","灞桥区","未央区","雁塔区","阎良区","临潼区","长安区","高陵区","咸阳区"}
  
     City["安康市区"]=[]string{"汉滨区","汉阴县","石泉县","宁陕县","紫阳县","岚皋县","平利县","镇平县","旬阳县","白河县",}
  
     Province["陕西"]=City
  
     City["西安景区"] = Scenery["西安"]
  
     City["安康景区"] = Scenery["安康"]
  
     for k,v := range Province{
  
         fmt.Println(k,v)
  
         for x,y := range v{
  
             fmt.Println(x,y)
  
         }
  
     }
  
}
  

  

  

  

  
#以上代码执行结果如下:
  
陕西 map[安康市区:[汉滨区 汉阴县 石泉县 宁陕县 紫阳县 岚皋县 平利县 镇平县 旬阳县 白河县] 西安景区:[秦始皇兵马俑 大雁塔 大唐芙蓉园 华清池 黄巢堡国家森林公园 西安碑林博物馆 骊山国家森林公园 西安城墙 秦始皇陵 翠华山] 安康景区:[中坝大峡谷 香溪洞 安康双龙生态旅游度假区 瀛湖生态旅游景区 简车湾休闲景区 南宫山 天书峡景区 汉江燕翔洞景区 飞渡峡-黄安坝景区 千层河] 西安市区:[新城区 碑林区 莲湖区 灞桥区 未央区 雁塔区 阎良区 临潼区 长安区 高陵区 咸阳区]]
  
西安景区 [秦始皇兵马俑 大雁塔 大唐芙蓉园 华清池 黄巢堡国家森林公园 西安碑林博物馆 骊山国家森林公园 西安城墙 秦始皇陵 翠华山]
  
安康景区 [中坝大峡谷 香溪洞 安康双龙生态旅游度假区 瀛湖生态旅游景区 简车湾休闲景区 南宫山 天书峡景区 汉江燕翔洞景区 飞渡峡-黄安坝景区 千层河]
  
西安市区 [新城区 碑林区 莲湖区 灞桥区 未央区 雁塔区 阎良区 临潼区 长安区 高陵区 咸阳区]
  
安康市区 [汉滨区 汉阴县 石泉县 宁陕县 紫阳县 岚皋县 平利县 镇平县 旬阳县 白河县]
  

  四.map的进阶知识
  1.map的挖坑
  Captial["北京"]["大兴区"]会发现这个值已经没有了,取而代之的是Captial["北京"]["密云县"]这是因为 Area 和 County 都是 map[string]int 类型的数据,Golang 直接把 ["大兴区"] 里的数据从 Area 替换成了 County,而不会递归地添加 map 中缺失的数据。
  

/*  
#!/usr/bin/env gorun
  
@author :yinzhengjie
  
Blog:http://www.cnblogs.com/yinzhengjie/tag/GO%E8%AF%AD%E8%A8%80%E7%9A%84%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
  
EMAIL:y1053419035@qq.com
  
*/
  

  
package main
  

  
import "fmt"
  

  
func main() {
  
     Captial := make(map[string]map[string]int)
  
     Area := make(map[string]int)
  
     Area["大兴区"] = 100
  
     Captial["北京"] = Area
  
     County := make(map[string]int)
  
     County["密云县"] = 200
  
     fmt.Println(Captial["北京"]["大兴区"]) //目前是可以访问到“Captial["北京"]["大兴区"]”的值的
  
     Captial["北京"] = County
  
     fmt.Println(Captial["北京"]["大兴区"]) //但是你执行了上一行的代码,你会发现你访问不到它的值100啦,但是你却发现可以访问下面一行代码的值。
  
     fmt.Println(Captial["北京"]["密云县"])
  
}
  

  

  

  

  
#以上代码执行结果如下:
  
100
  
0
  
200
  

  2.map的填坑
  你自己想到上面的解决方法了没?其实很简单,我们只要做一个条件判断即可,代码如下:
  

/*  
#!/usr/bin/env gorun
  
@author :yinzhengjie
  
Blog:http://www.cnblogs.com/yinzhengjie/tag/GO%E8%AF%AD%E8%A8%80%E7%9A%84%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
  
EMAIL:y1053419035@qq.com
  
*/
  

  
package main
  

  
import "fmt"
  

  
func main() {
  
     Captial := make(map[string]map[string]int)
  
     Area := make(map[string]int)
  
     Area["大兴区"] = 100
  
     Captial["北京"] = Area
  

  
     if _, ok := Captial["北京"]; ok {
  
         Captial["北京"]["密云县"] = 200  //判断,如果存在Captial["北京"]这个key就只做字典的追加操作。
  
     }else {
  
         County := make(map[string]int)
  
         Captial["北京"] = County
  
         County["密云县"] = 200 //如果不存在就
  
     }
  
     fmt.Println(Captial["北京"]["大兴区"]) //可以访问到“Captial["北京"]["大兴区"]”的值100啦。
  
     fmt.Println(Captial["北京"]["密云县"])
  
}
  

  

  

  
#以上代码执行结果如下:
  
100
  
200
  

  3.定义一个集合的思想
  了解过Python的童鞋,可能听说过集合,但是我要告诉你一个好消息和一个坏消息,你想先听哪一个?坏消息就是Golang没有集合这个概念;好消息是我们可以用Golang的make函数来实现集合的思想,下面跟我一起看个例子吧!
  

/*  
#!/usr/bin/env gorun
  
@author :yinzhengjie
  
Blog:http://www.cnblogs.com/yinzhengjie/tag/GO%E8%AF%AD%E8%A8%80%E7%9A%84%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
  
EMAIL:y1053419035@qq.com
  
*/
  

  
package main
  

  
import "fmt"
  

  
func main() {
  
     set := make(map[string]bool) //定义一个map
  
     set["yinzhengjie"] = true              //给已经存在的变量定义为真
  
     if set["yinzhengjie"] {
  
         fmt.Printf("已经存在明为yinzhengjie的key,其值为【%v】\n",set["yinzhengjie"])
  

  
     } else {
  
         fmt.Println("该变量不存在!")
  
     }
  

  
     if set["yzj"] {    //判断是否 存在变量
  
         fmt.Println("已经存在该变量")
  

  
     } else {
  
         fmt.Printf("不存在名为“yzj”的key,其值为【%v】\n",set["yzj"])
  

  
     }
  
     fmt.Println(set)  //我们来一起查看一下这个网站吧。
  
}
  

  

  

  

  
#以上代码执行结果如下:
  
已经存在该变量key,其值为【true】
  
不存在名为“yzj”的key,其值为【false】
  
map[yinzhengjie:true]
  

  4.map的寻址
  golang中的map并没有保证它们的value值的地址是不可变的,因为value值的地址很有可能被重新分配。在golang中,一个容量不断增长的map可能会导致原来map中的一些元素发生rehashing,使得他们被重新分配到新的storage location上,这样可能会导致原先得到的address变得不可用。就是所谓的map member 的 not addresable。
  换句话说,在golang设计的时候,map中的value值应该是地址不可达的,就是说直接取map中的元素的地址会报错.一个修改的办法就是把value值设置成为指针的形式,这样就相当于添加了一个额外的记录(entry),即使真正需要的那个值的位置发生了变化,也可以重定向(redirection)过去。
  

/*  
#!/usr/bin/env gorun
  
@author :yinzhengjie
  
Blog:http://www.cnblogs.com/yinzhengjie/tag/GO%E8%AF%AD%E8%A8%80%E7%9A%84%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
  
EMAIL:y1053419035@qq.com
  
*/
  

  
package main
  

  
import (
  
     "fmt"
  
)
  

  
type NameType struct {  //定义一个结构体,类似Python语言中定义一个类的概念。
  
     Blog string
  
}
  

  
func main() {
  
     BlogAddress := make(map[string]*NameType)
  
     BlogAddress["yinzhengjie"] = &NameType{} //这里赋值的是指针。
  
     BlogAddress["yinzhengjie"].Blog = "http://www.cnblogs.com/yinzhengjie"
  
     fmt.Println(BlogAddress)
  
}
  

  

  

  

  
#以上代码执行结果如下:
  
map[yinzhengjie:0xc042008230]
  

  5.扩展小知识:make和new的区别
  make 只能为 slice、map或 channel 类型分配内存并初始化,同时返回一个有初始值的 slice、map 或 channel 类型引用,不是指针。内建函数 new 用来分配内存,它的第一个参数是一个类型,不是一个值,它的返回值是一个指向新分配类型零值的指针。
  

  




运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-598783-1-1.html 上篇帖子: PHP7+Swoole比Nginx/Golang性能高75% 下篇帖子: Golang新起航!(编译安装go)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表