Go语言设计与实现(上)

Python013

Go语言设计与实现(上),第1张

基本设计思路

类型转换、类型断言、动态派发。iface,eface。

反射对象具有的方法:

编译优化:

内部实现:

实现 Context 接口有以下几个类型(空实现就忽略了):

互斥锁的控制逻辑:

设计思路:

(以上为写被读阻塞,下面是读被写阻塞)

总结,读写锁的设计还是非常巧妙的:

设计思路:

WaitGroup 有三个暴露的函数:

部件:

设计思路:

结构:

Once 只暴露了一个方法:

实现:

三个关键点:

细节

让多协程任务的开始执行时间可控(按顺序或归一)。(Context 是控制结束时间)

设计思路: 通过一个锁和内置的 notifyList 队列实现,Wait() 会生成票据,并将等待协程信息加入链表中,等待控制协程中发送信号通知一个(Signal())或所有(Boardcast())等待者(内部实现是通过票据通知的)来控制协程解除阻塞。

暴露四个函数:

实现细节:

部件:

包: golang.org/x/sync/errgroup

作用:开启 func() error 函数签名的协程,在同 Group 下协程并发执行过程并收集首次 err 错误。通过 Context 的传入,还可以控制在首次 err 出现时就终止组内各协程。

设计思路:

结构:

暴露的方法:

实现细节:

注意问题:

包: "golang.org/x/sync/semaphore"

作用:排队借资源(如钱,有借有还)的一种场景。此包相当于对底层信号量的一种暴露。

设计思路:有一定数量的资源 Weight,每一个 waiter 携带一个 channel 和要借的数量 n。通过队列排队执行借贷。

结构:

暴露方法:

细节:

部件:

细节:

包: "golang.org/x/sync/singleflight"

作用:防击穿。瞬时的相同请求只调用一次,response 被所有相同请求共享。

设计思路:按请求的 key 分组(一个 *call 是一个组,用 map 映射存储组),每个组只进行一次访问,组内每个协程会获得对应结果的一个拷贝。

结构:

逻辑:

细节:

部件:

如有错误,请批评指正。

(1)、语法:<结果类型>:= <目标类型>( <表达式>)

(2)、类型转换是用来在不同但相互兼容的类型之间的相互转换的方式,所以,当类型不兼容的时候,是无法转换的。如下:

一般来说,我们不会直接使用ASCII码来处理,因为这样不够直观。比如你说的判定输入是否是字母,是否是数字,那么有个比较直观的方法来处理。如果你看过ASCII码表,那么你就知道字数和字母在ASCII码表中都是连续的,所以这个就比较好解决了。

判定字符ch是否是数字:

if(ch>='0' &&ch<='9')

判定字符ch是否是字母:

if(ch>='a' &&ch<='z' || ch>='A' &&ch<='Z')

当然,有已经定义好的库函数用来判定是否数字和字母,不要加加载头文件<ctype.h>

判定字符ch是否是数字:

if(isalnum(ch))

判定字符ch是否是字母:

if(isalpha(ch))

这两个函数都是判定成立,结果是true也就是1,判定不成立,结果是false,也就是0.