一、学习指引
二、Ubuntu系统
操作与使用:https://zhuanlan.zhihu.com/p/672688377
linux常用命令:https://blog.csdn.net/m0_46422300/article/details/104645072
三、环境安装和配置
在linux系统中安装go环境:https://www.bilibili.com/video/BV1gf4y1r79E?p=2&vd_source=7ac1840ef91fce196a35d848a3779e29
在linux系统中安装goland:https://blog.csdn.net/sanqima/article/details/113623671
goland常用快捷键:https://zhuanlan.zhihu.com/p/548611534
goland上手:https://zhuanlan.zhihu.com/p/120347718 目前在使用go.mod方式下,不需要进行gopath的设置也行
goroot&gopath&gomodule参见此文:https://blog.csdn.net/qq_38151401/article/details/105729884
四、Go基础夯实
4.1 go语言结构
环境变量配置:
package&module:https://juejin.cn/post/6869570760738865166
4.2 变量和常量
介绍:https://zhuanlan.zhihu.com/p/143087271
注意点:
只允许在函数体内使用语法糖对变量进行声明和赋值
声明了一个局部变量却没有在相同的代码块使用,同样会编译错误
全局变量允许声明但不使用
全局变量的生命周期是程序存活时间
在不发生内存逃逸的情况下,局部变量是函数存活时间
4.3 go语言运算符
介绍:https://segmentfault.com/a/1190000044201272
运算符优先级:
4.4 go语言结构体
介绍:https://blog.csdn.net/m0_37710023/article/details/107657413 https://zhuanlan.zhihu.com/p/654946733
4.5 go语言数组与切片
数组介绍:https://www.runoob.com/go/go-arrays.html
切片介绍:https://zhuanlan.zhihu.com/p/629420925
map介绍:https://blog.csdn.net/weixin_43529465/article/details/129036783
map底层原理:https://zhuanlan.zhihu.com/p/460958342
4.6 go语言条件句
介绍:https://blog.csdn.net/wohu1104/article/details/99006545
if 语句特点:
if 后面的条件判断子句不需要用小括号括起来;
{ 必须放在行尾,和 if 或者 else if 放在一行;
if 后面可以带一个简单的初始化语句,并以分号分割,该简单语句声明的变量的作用域是整个 if 语句块,包括后面的 else if 和 else 分支;
if 分支语句遇到 return 后直接返回,遇到 break 则跳过 break 下方的 if 语句块;
switch语句特点:
switch 和 if 语句一样, switch 后面可以带一个可选的简单的初始化语句;
switch 后面的表达式也是可选的,如果没有表达式, 则 case 子句是一个布尔表达式,而不是一个值,此时就相当于多重 if else 语句;
switch 条件表达式的值不像 C/C++ 语言那样必须限制为整数常量, 表达式不需要为常量,甚至不需要为整数,可以是任意支持相等比较运算的类型变量;
switch 语句用于基于不同条件执行不同动作,每一个 case 分支都是唯一的,从上至下逐一测试,直到匹配为止;
switch 语句执行的过程从上至下,直到找到匹配项,匹配项后面也不需要再加 break ;
switch 默认情况下 case 最后自带 break 语句,匹配成功后就不会执行其他 case,如果我们需要执行后面的 case,可以使用 fallthrough ;
switch 支持 default 语句, 当所有的 case 分支都不符合时, 执行 default 语句, 并且 default 语句可以放到任意位置,并不影响 switch 的判断逻辑;
4.7 go语言循环
介绍:https://blog.csdn.net/weixin_44211968/article/details/121251817
4.8 go语言函数
介绍:https://www.runoob.com/go/go-functions.html
闭包:(匿名函数+捕获的变量)
Gopackage main import "fmt" func adder() func(int) int { sum := 0 return func(x int) int { fmt.Println("执行前 sum =", sum) sum += x return sum } } func main() { pos := adder() for i := 0; i < 4; i++ { fmt.Println("执行后 sum =", pos(1)) }
以上程序执行过程:
当程序执行main函数时,首先调用adder函数并将返回的闭包函数赋值给pos变量。在adder函数中,定义了一个sum变量,并返回一个闭包函数,闭包函数引用了外部的sum变量。
接着进入for循环,循环4次。每次循环中调用pos(1),传入参数1。闭包函数内部会打印当前sum的值,然后将参数值加到sum上,并返回新的sum值。
下面是程序的运行流程:
i=0 时,执行 pos(1):
输出 "执行前 sum = 0"
sum = sum + 1,即 sum = 0 + 1 = 1
输出 "执行后 sum = 1"
i=1 时,执行 pos(1):
输出 "执行前 sum = 1",之前的sum值为1
sum = sum + 1,即 sum = 1 + 1 = 2
输出 "执行后 sum = 2"
i=2 时,执行 pos(1):
输出 "执行前 sum = 2",之前的sum值为2
sum = sum + 1,即 sum = 2 + 1 = 3
输出 "执行后 sum = 3"
i=3 时,执行 pos(1):
输出 "执行前 sum = 3",之前的sum值为3
sum = sum + 1,即 sum = 3 + 1 = 4
输出 "执行后 sum = 4"
通过闭包函数,sum变量得以保留并且可以在每次调用闭包函数时被修改和访问,形成了类似于对象的状态。这种特性使得闭包函数在Go语言中非常灵活和强大。
adder函数在main函数中被调用并返回闭包函数给pos变量时,adder函数的生命周期会至少持续到程序执行完毕。因为返回的闭包函数中引用了adder函数作用域内的sum变量,所以add函数不会在其作用域结束后立即被销毁,而是会保持活跃状态,直至所有引用它的闭包函数被销毁。(在这个例子中,由于闭包函数持续引用着adder函数作用域内的变量,adder函数的生命周期会持续到所有引用它的闭包函数都被销毁为止。)
4.9 go语言指针
介绍:https://zhuanlan.zhihu.com/p/630590733
make与new的区别:https://c.biancheng.net/view/5722.html#
4.10 go语言方法
介绍:https://blog.csdn.net/wohu1104/article/details/106202918
方法是面向对象的,函数是面向过程的
接口类型不能作为方法的receiver基类,但是可以作为函数的参数和返回值
4.11 go语言接口
介绍:https://juejin.cn/post/7060471869085843487
一个对象只要全部实现了接口中的方法,那么就实现了这个接口(无论是自定义的还是内置的)。换句话说,接口就是一个需要实现的方法列表。一个对象可以实现多个接口,一个接口也可以被多个对象实现。
4.12 go语言error
介绍:https://cloud.tencent.com/developer/article/2232185
4.13 go语言defer
go语言的一个关键字,用在函数或者方法前面,延迟函数的执行:defer func()
延迟函数什么时候被调用:(一定会被执行,无论是否正常退出)
函数return的时候
发生panic的时候
延迟调用的语法规则
defer关键字后面表达式必须是函数或者方法调用
延迟内容不能被括号括起来
多个defer同时出现时,按倒序执行,先定义的后执行
defer的使用场景
资源释放
配合recover捕获异常
defer考点:
代码考察,通过defer修改函数放回值,考察输出。
defer与return的关系:https://cloud.tencent.com/developer/article/1453355(非常好,一看就懂)
return非原子操作,其执行的过程可分为三步:
设置返回值,对于无名返回值,这个返回值保存在一个临时空间中(该空间不同于函数中为局部变量i开辟大空间),defer时看不到这个临时空间(与局部变量i地址不同),只能看到局部变量的地址,所以defer函数中对i的操作也能正常执行,但是因为不是对返回值空间进行的操作,所以返回值只会为局部变量被定义时取得的那个值(因为设置返回值快于defer,故不是defer函数执行后的i值);而对于有名返回值,就保存在已命名的变量中,故defer能看到这个返回值(同一地址),后续的操作也对这个地址的返回值操作。
执行defer语句
将结果返回
4.14 go异常捕获
介绍:https://www.cnblogs.com/open-yang/p/11256858.html
defer嵌套写法的解析:https://juejin.cn/post/7197361396220100663
Go// 第一种 func main() { x := 1 y := 2 defer calcTest("AA", x, calcTest("A", x, y)) x = 10 defer calcTest("BB", x, calcTest("B", x, y)) y = 20 } func calcTest(index string, a, b int) int { ret := a + b fmt.Println(index, a, b, ret) return ret } /* A 1 2 3 B 10 2 12 BB 10 12 22 AA 1 3 4 */ func main() { x := 1 y := 2 defer func() { calcTest("AA", x, calcTest("A", x, y)) }() x = 10 defer func() { calcTest("BB", x, calcTest("B", x, y)) }() y = 20 } /* B 10 20 30 BB 10 30 40 A 10 20 30 AA 10 30 40 */
defer语句后面,如果未使用嵌套写法,这时函数里的参数值都得为确定值(先确定参数,但推迟整个函数的执行),即不会因为后面的修改而影响;如果使用嵌套写法,由于匿名函数无参数,需进入函数体内后才开始确定calcTest里面的参数,故得到的是x,y的最终结果; 所以,例子1执行顺序:先执行输出A→B,然后defer逆序执行输出BB→AA;例子2执行顺序:直接defer逆序执行,顺序为B→BB→A→AA,每一步带入相应的x y值,即可推导出结果。 第一种是非匿名函数写法
初始化变量 x 为 1
初始化变量 y 为 2
执行 defer calcTest("AA", x, calcTest("A", x, y))
这里会先计算 calcTest("A", x, y),即调用 calcTest 函数并传入参数 "A", 1, 2
"A 1 2 3" 被打印出来
然后再计算 calcTest("AA", x, 3),即调用 calcTest 函数并传入参数 "AA", 1, 3
"AA 1 3 4" 被打印出来
注意:defer 语句中的函数调用会被推迟到当前函数执行结束之前才执行
将变量 x 更新为 10
执行 defer calcTest("BB", x, calcTest("B", x, y))
这里会先计算 calcTest("B", x, y),即调用 calcTest 函数并传入参数 "B", 10, 2
"B 10 2 12" 被打印出来
然后再计算 calcTest("BB", x, 12),即调用 calcTest 函数并传入参数 "BB", 10, 12
"BB 10 12 22" 被打印出来
将变量 y 更新为 20
函数执行结束
第二种是匿名函数的写法 由于使用了defer关键字,所以两个匿名函数都会被推迟到函数执行结束之前才执行,由于匿名函数无参数,所以无需提前确定,所以也是到那个时候才开始进入函数体内后才开始确定calcTest的参数。
recover和panic可以总结为以下两点:
recover只能回复当前函数级或以当前函数为首的调用链中的函数中的panic(),恢复后当前调用recover的函数结束,但是调用此函数的函数继续执行
函数发生了panic之后会一直向上传递,如果直至main函数都没有recover(),程序将终止,如果是碰见了recover(),将被recover捕获
recover必须搭配defer来使用,否则panic捕获不到;
defer一定要在可能引发panic的语句之前定义;
4.15 依赖管理
介绍:https://blog.csdn.net/qq_31930499/article/details/101108056
下载失败可看:https://zhuanlan.zhihu.com/p/525542452
相关阅读
大家都在找:
golang:golang官网
开发语言:开发语言有哪几种
后端:后端是做什么的
发表评论
2024-07-17 19:07:46回复
1. 4.1 go语言结构
2. 4.2 变量与常量
3. 4.3 go语言运算符
4. 4.4 go语言结构体
5. 4.5 go语言数组与切片
6. 4.6 go语言条件句
7. 4.7 go语言函数
8. 4.8 go语言接口
9. 4.9 go语言异常捕获
10. 4.10 go语言defer关键字
11. 4.11 go语言循环
12. 4.12 go语言方法
13. 4.13 go语言的defer使用
14. 4.14 go语言异常捕获
15. 4.15 依赖管理