Datawhale组对任务Task05是学习map和string的用法。
Go-map
map是key-value数据结构,又称为字段或者关联数组。类似其它编程语言的集合。
map的声明
基本语法
var map变量名 map[keytype] valuetypevar a map[string]stringvar a map[string]intvar a map[int]stringvar a map[string]map[string]string //key是一个string,值是一个map
golang中的map的key可以是很多种类型,比如bool,数字,string,指针,channel,还可以是只包含前面几个类型的接口,结构体,数组通常key为int、string
注意:slice,map还有function不可以,因为这几个没法用==来判断
注意:声明是不会分配内存的,初始化需要make,分配内存后才能赋值和使用。
var a map[int]int a = make(map[int]int, 2) a[1] = 2 a[2] = 3 fmt.Println(a) //map[1:2 2:3].
①map在使用前一定要make
②map的key是不能重复,如果重复了,则以最后这个key-value为准 ③map的value是可以相同的.
④map的key-value是无序的
map的使用
//方式一var a map[int]int a = make(map[int]int, 2) a[1] = 2 a[2] = 3 fmt.Println(a) //map[1:2 2:3]//方式二,注意这种方式可以在括号内使用" : "来添加,不要忘记" , " b := map[string]string{ "城市1": "上海", "城市2": "武汉", } b["城市3"]="北京" //这里同样可以使用这种操作进行添加数据 fmt.Println(b) //map[城市1:上海 城市2:武汉] //方式三 c := make(map[string]string, 3) c["yaojing1"] = "牛魔" c["yaojing2"] = "狐狸精" fmt.Println(c) //map[yaojing1:牛魔 yaojing2:狐狸精]
map的增删改查操作
map增加和更新
map["key"]=value //如果key还没有,就是增加,如果key存在就是修改。
map删除
delete(map,"key"),delete是一个内置函数,如果key存在,就删除该key-value,如果key不存在,不操作,但是也不会报错。
b := map[string]string{ "城市1": "上海", "城市2": "武汉", } b["城市3"]="北京" delete(b,"城市3") fmt.Println(b)
如果我们要删除map的所有key,在golang中没有一个专门的方法一次删除,可以遍历一下key,逐个删除 或者map=make(...),make一个新的,让原来的成为垃圾,被gc回收。
//b是上一个城市的mapb = make(map[string]string, 3) fmt.Println(b) //map[]
map查找
val, findres := b["城市2"] //利用这种形式返回map值和一个bool型的值 if findres { fmt.Printf("存在这个值%v\n", val) } else { fmt.Println("不存在这个数据") }//存在这个值武汉
map遍历
map的遍历只能使用for-range的结构遍历
map切片
切片的数据类型如果是map,则我们称为slice of map,map切片,这样使用则map个数就可以动态变化了。
map排序
①golang中没有一个专门的方法针对map的key进行排序
②golang中的map默认是无序的,注意也不是按照添加的顺序存放的,你每次遍历,得到的输出可能不一样.
③golang中map的排序,是先将key进行排序,然后根据key值遍历输出即可
map使用细节
map是引用类型,遵守引用类型传递的机制,在一个函数接收map,修改后,会直接修改原来的map
map的容量达到后,再想map增加元素,会自动扩容,并不会发生panic,也就是说map能动态的增长键值对(key-value)
map的value也经常使用struct类型,更适合管理复杂的数据(比前面value是一个map更好),比如value为Student结构体。
字符串
字符串是一种值类型,在创建字符串之后其值是不可变的,也就是说下面这样操作是不允许的。
s := "hello"s[0] = 'T' //编译器会提示cannot assign to s[0]。
string底层是一个byte数组,因此string也可以进行切片处理.
string和切片在内存的形式
如果需要修改字符串,可以先将string->[ ]byte/或者[ ]rune->修改->重写转成string,通俗点说即将其转换为字节切片,再将其转换为字符串,但是也同样需要重新分配内存。
var str1 stringstr1 = "qwertyui"arr := []byte(str1) //转成[]bytearr[3]='b' //修改str2:=string(arr) //重写fmt.Println(str2)
续昨日的控制结构
switch Go 的 switch 非常灵活。表达式不必是常量或整数,执行的过程从上至下,直到找到匹 配项,而如果 switch 没有表达式,它会匹配 true 。这产生一种可能——使用 switch 编写 if-else-if-else 判断序列。func unhex(c byte)byte { switch { case'0' <= c && c <= '9': return c - '0' case'a' <= c && c <= 'f': return c - 'a' + 10 case'A' <= c && c <= 'F': return c - 'A' + 10 } return 0}
它不会匹配失败后自动向下尝试,但是可以使用
fallthrough
使其这样做。没
有
fallthrough
:
switch i{ case 0: //空的case体 case 1:f() //当i == 0时,f不会被调用!}
而这样:
switch i{ case 0: fallthrough case 1: f() //当i == 0时,f会被调用}
另外,用default可以指定当其他所有分支都不匹配的时候的行为。
switch i{ case 0: case 1: f() default: g() //当i不等于0或1时调用}
分支可以使用逗号分隔的列表。
func shouldEscape(c byte) bool { switch c { case ' ', '?', '&', '=', '#', '+': as return true } return false}
这里有一个使用两个switch对字节数组进行比较的例子:
// 0 比较返回两个字节数组字典数序先后的整数。//如果a == b返回0,如果a < b返回-1,而如果a > b返回+1;func Compare(a, b []byte) int { for i := 0; i <len(a) && i <len(b); i++ { switch { case a[i] > b[i]: return 1 case a[i] < b[i]: return -1 } } switch { // 1 长度不同,则不相等; case len(a) <len(b): return -1 case len(a) >len(b): return 1 } return0 // 2 字符串相等。 }
今日圆满的完成了课程设计答辩,虽然还有很多不完善的地方,老师并没有因此批评我们,给我们提了很多意见。另外一个老师超严上天保佑,没有被分配到那位老师手上。心里的一块大石头终于落地了终于可以好好复习了!