这是我参与「第三届青训营 -后端场」笔记创作活动的第1篇笔记
前文
这是第一次参加字节青训营的课程,听完之后受益匪浅,也是感受到字节的氛围是挺好的,在此之前是一直学Java后端的,第一次接触go,听完老师的讲解,觉得上手还是很快的,只不过老师语速有点快,后面有点跟不上,整体还是有个了解。
目前对go的了解还是很肤浅的,所以希望通过后面课程对go有进一步的深入和了解,形成自己的知识体系
下面进入今天的笔记环节,我是结合相关书籍对一些东西进行补充
正文
1.1 命名规范
Go语言中的函数名、变量名、常量名、类型名、语句标号和包名等所有的命名,都遵循一个简单的命名规则:一个名字必须以一个字母(Unicode字母)或下划线开头,后面可以跟任意数量的字母、数字或下划线。
1.2 变量
变量的几种创建方式
- `var 变量名字 类型 = 表达式
- 名字 := 表达式 //i, j = j, i // 交换 i 和 j 的值、i := 100
- new函数 //p := new(int) // p, *int 类型, 指向匿名的 int 变量`
1.3 数组
数组初始化
var q [3]int = [3]int{1, 2, 3}
var r [3]int = [3]int{1, 2}
fmt.Println(r[2]) // "0"
在数组字面值中,如果在数组的长度位置出现的是“...”省略号,则表示数组的长度是根据初始化值的个数来计算。因此,上面q数组的定义可以简化为
q := [...]int{1, 2, 3}
fmt.Printf("%T\n", q) // "[3]int"
数组的长度是数组类型的一个组成部分,因此[3]int和[4]int是两种不同的数组类型。数组的长度必须是常量表达式,因为数组的长度需要在编译阶段确定。
1.4 切片
Slice(切片)代表变长的序列,序列中每个元素都有相同的类型。一个slice类型一般写作[]T,其中T代表slice中元素的类型;slice的语法和数组很像,只是没有固定长度而已。
slice的append函数
runes = append(runes, r)``
1.5 map
其中K对应的key必须是支持==比较运算符的数据类型,所以map可以通过测试key是否相等来判断是否已经存在。虽然浮点数类型也是支持相等运算符比较的,但是将浮点数用做key类型则是一个坏的想法,正如第三章提到的,最坏的情况是可能出现的NaN和任何浮点数都不相等。
Map的创建
内置的make函数可以创建一个map:
ages := make(map[string]int) // mapping from strings to ints
我们也可以用map字面值的语法创建map,同时还可以指定一些最初的key/value:
ages := map[string]int{
"alice": 31,
"charlie": 34,
}
这相当于
ages := make(map[string]int)
ages["alice"] = 31
ages["charlie"] = 34
因此,另一种创建空的map的表达式是map[string]int{}。
Map的访问
Map中的元素通过key对应的下标语法访问:
ages["alice"] = 32
fmt.Println(ages["alice"]) // "32"
Map的删除
使用内置的delete函数可以删除元素:
delete(ages, "alice") // remove element ages["alice"]
但是map中的元素并不是一个变量,因此我们不能对map的元素进行取址操作:
_ = &ages["bob"] // compile error: cannot take address of map element
禁止对map元素取址的原因是map可能随着元素数量的增长而重新分配更大的内存空间,从而可能导致之前的地址无效。
Map的遍历
要想遍历map中全部的key/value对的话,可以使用range风格的for循环实现,和之前的slice遍历语法类似。下面的迭代语句将在每次迭代时设置name和age变量,它们对应下一个键/值对:
for name, age := range ages {
fmt.Printf("%s\t%d\n", name, age)
}
Map的迭代顺序是不确定的,并且不同的哈希函数实现可能导致不同的遍历顺序。在实践中,遍历的顺序是随机的,每一次遍历的顺序都不相同。
写在最后
今天的笔记暂时梳理到这,后面会通过课程深入和阅读书籍进一步完善