go-study
Go Study
相关代码见:https://github.com/WD-2711/go-study
Go-section-2
运行go程序的方式:
- go run xx.go
- go install xx.go,之后可以用$GOPATH/bin/xx 运行该程序
1 | package main |
Go-section-3
1 | var age int |
输出如下:
1 | my age is 0 |
Go-section-4
基本数据类型:
1 | int8,int16,int32,int64,int |
具体见/go-class/dataType.go
Go-section-5
具体见/go-class/constVar.go
Go-section-6
具体见/go-class/func.go
Go-section-7 包
- 创建geometry文件夹,编写完geometry.go,运行cp -r /root/code/go-code/go-class/sec-7/geometry /usr/local/go/src,接着cd /usr/local/go/src运行 go install geometry,这个时候就会在/usr/local/go/bin文件夹下生成一个geometry的可运行程序
- cd /usr/local/go/bin && ./geometry 即可
创建自定义的包
- 在geometry文件夹中创建rectangle文件夹并在里面编写rectprops.go文件,按上述操作进行运行
导出名
- rectprops.go中的函数首字母都是大写的,这代表可以被导出,其他包可以访问到这些函数
Init
- 所有包中都可以包含Init函数,此函数没有任何返回值与参数,其用于初始化任务,也可以在程序开始执行之前验证程序的正确性
- 包的初始化顺序如下:(1)初始化包级别的变量。(2)调用Init函数(一个包中可以有多个Init函数)
注:一个包可以被导入多次,但是它只会被初始化一次。
空白标识符
- 导入了包,但是不在代码中使用它是违法的。
- 可以用空白标识符来避免这种问题:
1 | import (_ "geometry/rectangle") |
具体见/go-class/sec-7
Go-section-8 分支语句
一个很坑的点就是:(原因是go看到}
后面没有字符就自动插入;
)
要这么写
1 | if condition { |
不能这么写
1 | if condition { |
具体见/go-class/ifElse.go
Go-section-9 循环
具体见/go-class/cycle.go
Go-section-10 switch
- case 不允许出现重复项
- fallthrough意思是执行完一个case之后,不会跳出来,反而进行下一个case的判断
具体见/go-class/switch.go
Go-section-11 array&切片
具体见/go-class/arr-slice.go
Go-section-12 Maps
- map是将value与key关联的数据类型
具体见/go-class/maps.go
Go-section-13 字符串
具体见/go-class/str.go
Go-section-14 可变参数函数
- 可变参数函数就是参数个数可以改变的函数,其最后一个参数为
...T
,例如
1 | func append(slice []Type, elems ...Type) []Type |
具体见/go-class/argChangeFuc.go
Go-section-15 指针
1.指针变量的类型为*T
,该指针指向了一个T
类型的变量
具体见/go-class/pointer.go
Go-section-16 结构体
具体见/go-class/structure.go与/go-class/sec-16
sec-16主要是讲导出结构体
1 | cp -r /root/code/go-code/go-class/sec-16/structs /usr/local/go/src |
具体见/go-class/structure.go
Go-section-17 方法
- 方法其实就是函数,只不过在func与方法名之间加了一个特殊的接收器类型,例如:
1 | func (t Type) methodName (params list){ |
为啥需要方法呢?(1)Go不支持类,且不是纯粹的面向对象的编程语言,基于类型的方法是一种实现和类相似行为的途径。(2)相同名字的方法可以定义在不同的类型上,而相同名字的函数是不被允许的。
什么时候用指针接收器,什么时候用值接收器?当要求方法内部的接收器的所做的改变对调用者可见时,要用指针接收器。
方法中的值接收器 and 函数中的值参数。(1)当函数中是值参数,它只能接受值参数;当方法中有一个值接收器,那么它可以接受值接收器和指针接收器。(2)当函数中是指针参数,那么它只能接受指针参数;当方法中一个指针接收器,那么它可以接受值接收器和指针接收器。
具体见/go-class/method.go
Go-section-18 接口(重点)
接口定义一个对象的行为,接口只定义了对象应该做什么,但是要怎么去做还是要对象本身去决定。
Go中,接口就是方法的集合。当一个类型定义了接口中的所有方法,我们就说它实现了该接口。
具体见/go-class/interface.go
Go-section-19 接口2(重点)
具体见/go-class/interface2.go
Go-section-20 并发
- 并发与并行的区别(你懂的)
Go-section-21 协程
啥是协程?协程是与其他函数或方法一起并发运行的函数或方法,可以看作是轻量级的线程。
协程相对于线程的优势?(1)成本极低。堆栈大小只有几kb。(2)协程复用数量更少的OS线程。如果线程中的某一个协程发生了阻塞,那么系统会创建一个新的OS线程,并把其余的Go协程都移动到这个新的OS线程。(3)协程使用信道来通信。
具体见/go-class/coroutine.go
Go-section-22 信道
具体见/go-class/channel.go
Go-section-23 缓冲信道与工作池(重点)
啥是缓冲信道?就是有容量的信道。
缓冲信道的长度指的是当前存的值的数量,缓冲信道的容量就是最多能放多少值。
WaitGroup用于等待一批协程执行结束,直到这些协程全执行完毕后,程序才会继续往下运行。
工作池就是一组等待任务分配的线程,一旦完成了所分配的任务,这些线程可以继续等待任务的分配。pool.go中写了一个工作池,其功能如下:(1)创建了一个Go协程池,监听一个等待作业分配的输入型缓冲信道。(2)将作业添加到输入型缓冲信道中。(3)作业完成后,将结果写入到一个输出型缓冲信道。(4)从输出型缓冲信道中读取并打印结果。
具体见/go-class/pool.go
Go-section-24 select
select会在多个发送/接收信道操作中进行选择,select会一直阻塞,直到发送/接收操作准备就绪。如果有多个信道准备完毕,那么select会随机选取其中之一执行。
select的应用:想要把输出尽快的返回给用户,输出存储在世界各地的服务器上。
具体见/go-class/select.go
Go-section-25 mutex
- mutex就是互斥量,相应的就有临界区的概念,你也懂得哦
1 | mutex.Lock() |
Lock与Unlock之间的代码只能由一个Go协程执行,所以可以避免竞态条件。
具体见/go-class/mutex.go
Go-section-26 结构体取代类
- Go虽然没有类,但是也可以面向对象编程,就是用接口和结构体来实现类的功能。
具体见/go-class/sec-26
Go-section-27 组合取代继承
意思就是多个结构体嵌套,然后用切片可以组合在一起。
具体见/go-class/nest.go
Go-section-28 defer
defer的定义:含有defer的函数,在函数要返回之前,调用另一个函数。
defer的应用:当函数在当前代码流无关的环境下调用时,可以使用defer。
具体见/go-class/defer.go
Go-section-29 多态
- 同一个代码可以在多种不同的类型上运行,例如:
1 | func printValue(val interface{}) { |
具体见/go-class/defer.go
Go-section-30 错误
- error是一个接口,定义如下:
1 | type error interface { |
具体见/go-class/errProcess.go
Go-section-31 自定义错误
- 使用New函数创建自定义错误
具体见/go-class/errUserDefine.go
Go-section-32 panic与recover
上一节说的error是用来处理异常情况的,一般来说error就够用了。但是有些情况,当程序发生异常时无法继续运行,这种情况下我们会使用panic来终止程序,当函数发生panic的时候,在执行完所有的延迟函数后,程序会中止运行。
当程序出现panic的时候,使用recover可以重新获得对该程序的控制权
panic&recover与try-catch-finally类似。
panic的使用场景:(1)发生了不能恢复的错误,例如web服务器无法绑定所要求的端口,因为如果不能绑定端口,那么啥也做不了。(2)发生了编程上的错误,例如有一个接收指针参数的方法,而其他人使用nil作为参数调用了它,此时可以使用panic,因为用nil参数调用了一个只能接收合法指针的方法。
留言
- 文章链接: https://wd-2711.tech/
- 版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-ND 4.0 许可协议。转载请注明出处!