二、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
- 闭包:(匿名函数+捕获的变量)
Go |
以上程序执行过程:
当程序执行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 |
defer语句后面,如果未使用嵌套写法,这时函数里的参数值都得为确定值(先确定参数,但推迟整个函数的执行),即不会因为后面的修改而影响;如果使用嵌套写法,由于匿名函数无参数,需进入函数体内后才开始确定calcTest里面的参数,故得到的是x,y的最终结果; 所以,例子1执行顺序:先执行输出A→B,然后defer逆序执行输出BB→AA;例子2执行顺序:直接defer逆序执行,顺序为B→BB→A→AA,每一步带入相应的x y值,即可推导出结果。 第一种是非匿名函数写法
|
第二种是匿名函数的写法 由于使用了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