这是我参与「第五届青训营 」笔记创作活动的第1天
本堂课重点内容
- Go语言背景知识
- Go基础语法
详细知识点介绍
Go语言背景知识
- Go语言具有高并发、语法简单、工具链完善、标准库丰富等优点。
- 字节由于早期团队非Java背景且Python具有性能问题选择了Go。
Go基础语法
由于我之前接触过Go语言,这里挑几个重点的讲。
变量
可以通过var加类型的方式定义变量:var a int,
也可以让编译器帮你类型推断:a:=3
条件分支(if-else)
条件不需要用括号包裹,但是语句块必须用大括号包裹。
循环
跟C相比,Go语言只有for循环,且for语句不需要加括号,但循环体必须加大括号。但for内部的三个部分与C是一样的,且可以在第一部分定义局部变量。
for n:=0; n<5; n++ {
fmt.Println(n)
}
switch
Go的switch执行完一个语句块后,默认不接着执行下一个,而是直接跳出,否则需要在语句块最后加fallthrough。
变量类型
Go里的变量主要分值类型和引用类型两种。值类型直接存储值,例如各种数字(int等)、字符串、数组、结构体等。引用类型类似指针,其对应的地址里存的是真正的数据,如指针、slice、channel、map等。
引用类型作为参数时,传入函数的是其地址,在函数内部对其的修改会影响原来的参数。 值类型可以用make初始化,它与new的区别是,不仅分配了一块内存,还将其初始化。
错误处理
在会发生异常的函数里,可以返回函数值和error类型两个参数。然后就是Go语言特色
val, err := f()
if err != nil {
//错误处理
}
实践练习例子
关于引用类型slice的一个例子。slice在达到容量之后会进行扩容,而扩容之后的那个slice就不是原来的silice了。
package main
import "fmt"
func f(x []int) {
//x = append(x, 4)
x[0] = 666
fmt.Println(x, cap(x))
}
func main() {
a := make([]int, 0)
a = append(a, 1)
a = append(a, 2)
f(a)
fmt.Println(a, cap(a))
}
若注释掉x = append(x, 4),以上代码的执行结果是:
[666 2] 2
[666 2] 2
若不注释,结果是:
[666 2 4] 4
[1 2] 2
这是因为在执行f函数前,a的容量和长度都是2,是满的。开始执行f时,由于slice是引用类型,参数x和a都是一样的,指向同一块内存。
若直接对x[0]进行修改,则a也一样会变。
但倘若往x中追加元素,由于x已满,会触发扩容,新产生一个容量为4(原容量翻倍)的slice赋值给x,此时x和a就不一样了。因此接下来对x的修改不会反映在a上。
避免这个问题的最简单办法是,一开始就给slice初始化足够的容量,确保其不会扩容。
课后个人总结
个人感觉,Go基础知识中需要注意的就是那几个引用类型,最好花点时间了解一下其实现原理。有时间的话再多看看Go的标准库的实现。