一、学习指引

二、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

相关阅读

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: