前言
Go语言中提供了映射关系容器为map
,类似Python中的字典。其内部使用散列表(hash)
实现、无序、为引用数据类型。
不同于Python字典之处是map的key可以为数字,在声明map时就需要指定 map中key和value的数据类型。
map的定义及基本操作
package main import "fmt" func main() { //定义了1个map变量,key是sring类型、value是int类型 var m1 map[string]int fmt.Println(m1 == nil) //还没有初始化(没有在内存中开辟空间) //初始化:估算好map的容量,避免程序运行期间在扩容 m1 = make(map[string]int, 10) m1["年龄"] = 18 fmt.Println(m1) fmt.Println(m1["年龄"]) //获取不存在的key v, ok := m1["姓名"] if !ok { fmt.Println("没有该key") } else { fmt.Println(v) } //直接获取不存在的key,返回对应类型的默认值 fmt.Println(m1["不存在的key"]) //遍历map的key和value m2 := make(map[string]string, 10) m2["姓名"] = "Martin" m2["性别"] = "男" for k, v := range m2 { fmt.Println(k, v) } //仅遍历map的keys for k := range m2 { fmt.Println(k) } //仅遍历map的values for _, v := range m2 { fmt.Println(v) } //删除map中的key delete(m2,"姓名") fmt.Println(m2) //删除map中不存在的key() no-option delete(m1,"不存在的key") /* go doc builtin.delete 查看内置函数的用法 func delete(m map[Type]Type1, key Type) The delete built-in function deletes the element with the specified key (m[key]) from the map. If m is nil or there is no such element, delete is a no-op. */ }
排序显示map
无论是Python的字典还是Go中的map,它们都是无序的。那么我们如何对map进行排序呢?就需要1些迂回的方法;
对map的key进行排序做成切片,然后遍历切片中的key逐一获取map中的元素。
package main import ( "fmt" "math/rand" //math包中有个rand模块 "sort" "time" ) func main() { //获取当前时间的 纳秒(随机数字) rand.Seed(time.Now().UnixNano()) //声明1个map存放{stud纳秒:分数 } var scoreMap = make(map[string]int, 200) for i := 0; i < 100; i++ { key := fmt.Sprintf("stud%2d", i) value := rand.Intn(100) //生成0-99的随机整数(作为分数) scoreMap[key] = value } var keys = make([]string, 0, 200) for key := range scoreMap { keys = append(keys, key) } //安装字符串进行排序 sort.Strings(keys) //通过排序后的key,对map逐一获取值 for _, key := range keys { fmt.Println(scoreMap[key]) } }
切片和map组合数据类型
如何在go里面组织这种多维度的数据类型?
1.make创造1个元素为map的切片
[{"key1":"v1"},{"key2":"v2"}]
创造1个切片[],内部的元素=map[int]string
2.make创造 值(value)为map的切片
{"ke1":["v1","v2","v3"] }
创造 1个map key为 [string] 值为[]string
package main import ( "fmt" ) //map和slice组合 func main() { //1.创造1个切片[],内部的元素=map[int]string var s1 = make([]map[int]string, 10, 10) //注意需要对 内部的map也进行初始化 s1[0] = make(map[int]string, 1) s1[0][10] = "北京" fmt.Println(s1) //2.创造1个map var m2 = make(map[string][]string, 10) //对map中的切片进行初始化 m2["北京市"] = []string{"朝阳区", "海淀区", "昌平区"} fmt.Println(m2) }
总结
目前主要学到了,Go中的数据类型(string、int、bool、pointer、arry、slice、map)以及怎么定义该数据类型的变量,以便于在使用Go的情况下,存放不同数据模型的数据。
ackage main import "fmt" func main() { //声明1个字符串变量 var name string fmt.Println(name) //声明1个数组变量 var a1 [3]int fmt.Println(a1) //声明完了就有默认值 //声明1个切片类型的变量 var s1 []int fmt.Println(s1 == nil) //声明二维数组 var a3 [3][3]int //对二维数组进行初始化 a3 = [3][3]int{ [3]int{1, 2, 3}, [3]int{4, 5, 6}, [3]int{7, 8, 8}, } fmt.Println(a3) // a4 := [3]int{1, 2, 3} a5 := modifyArry(a4) fmt.Println(a4) fmt.Println(a5) s2 := []string{"河北", "保定", "唐县"} s3 := modifySlice(s2) fmt.Println(s2) fmt.Println(s3) //map数据类型 var m1 map[string]int //注意使用make函数对map进行初始化 m1 = make(map[string]int, 10) //直接使用map m2:=make(map[string]int) m2["name"]=12 fmt.Println(m1,m2) } //数组是值类型:修改数组时,会复制 1个新的数组让我们修改 func modifyArry(a1 [3]int) (ret [3]int) { a1[0] = 100 return a1 } //切片是引用类型:修改切片时,不会复制1个新的切片让我们修改(修改原来的) func modifySlice(s2 []string) (ret2 []string) { s2[0] = "河北省" return s2 }
练习
// // //遍历数组 // package main // import ( // "fmt" // ) // func main() { // //根据索引访问元素 // var cities = [...]string{"北京", "上海", "深圳"} // for i := 0; i < len(cities); i++ { // fmt.Printf("%s ", cities[i]) // } // //遍历数组 // for i, v := range cities { // fmt.Println(i, v) // } // } // package main // import ( // "fmt" // ) // func main() { // //arry数值类型辩证 // a1 := [...]string{"河北", "河南", "山东"} // a2 := a1 // a1[len(a1)-1] = "山西" // fmt.Println(a1) //[河北 河南 山西] // fmt.Println(a2) //[河北 河南 山东] // } //练习题目 // package main // import ( // "fmt" // ) // func main() { // //1.求数组[1, 3, 5, 7, 8]所有元素的和 // arr1 := [...]int{1, 3, 5, 7, 8} // var sum int // for _, v := range arr1 { // sum += v // } // fmt.Println(sum) // /*找出数组中和为指定值的两个元素的下标,比如从数组[1, 3, 5, 7, 8]中找出和为8的两个元素的下标分别为(0,3)和(1,2)*/ // for i := 0; i < len(arr1); i++ { // for j := i + 1; j < len(arr1); j++ { // if arr1[i]+arr1[j] == 8 { // fmt.Printf("%d %d ", i, j) // } // } // } // } // package main // import "fmt" // func main() { // //声明1个字符串变量 // var name string // fmt.Println(name) // //声明1个数组变量 // var a1 [3]int // fmt.Println(a1) //声明完了就有默认值 // //声明1个切片类型的变量 // var s1 []int // fmt.Println(s1 == nil) // //声明二维数组 // var a3 [3][3]int // //对二维数组进行初始化 // a3 = [3][3]int{ // [3]int{1, 2, 3}, // [3]int{4, 5, 6}, // [3]int{7, 8, 8}, // } // fmt.Println(a3) // // // a4 := [3]int{1, 2, 3} // a5 := modifyArry(a4) // fmt.Println(a4) // fmt.Println(a5) // s2 := []string{"河北", "保定", "唐县"} // s3 := modifySlice(s2) // fmt.Println(s2) // fmt.Println(s3) // //map数据类型 // var m1 map[string]int // //注意使用make函数对map进行初始化 // m1 = make(map[string]int, 10) // //直接使用map // m2:=make(map[string]int) // m2["name"]=12 // fmt.Println(m1,m2) // } // //数组是值类型:修改数组时,会复制 1个新的数组让我们修改 // func modifyArry(a1 [3]int) (ret [3]int) { // a1[0] = 100 // return a1 // } // //切片是引用类型:修改切片时,不会复制1个新的切片让我们修改(修改原来的) // func modifySlice(s2 []string) (ret2 []string) { // s2[0] = "河北省" // return s2 // } package main import ( "fmt" "strings" "unicode" ) func main() { var ChineseCount int s1 := "hello你好少年" for _, c := range s1 { //1.判断字符是否为汉字(rune类型) if unicode.Is(unicode.Han, c) { ChineseCount++ } } fmt.Printf("汉字的数量为:%d ", ChineseCount) //2.判断句子中单词出现的次数(word count) word := "how do you do" //英文句子中单词以空格隔开 WordArry := strings.Split(word, " ") wordCountMap := make(map[string]int) for _, v := range WordArry { _, ok := wordCountMap[v] if ok { wordCountMap[v]++ } else { wordCountMap[v] = 1 } } fmt.Println(wordCountMap) //3.判断句子是否为以下回文句型 /* 上海自来水来自海上 山西运煤车煤运西山 */ LoopSting := "山西运煤车煤运西山" //定义1个存放rune字符串(汉字)的切片 RuneSlice := make([]rune, 0, len(LoopSting)) for _, c := range LoopSting { RuneSlice = append(RuneSlice, c) } for i := 0; i < len(RuneSlice)/2; i++ { if RuneSlice[i] != RuneSlice[len(RuneSlice)-i-1] { fmt.Println("不是回文句型") return //在main函数中 return 程序结束 } } fmt.Println("是回文句型") }