基本设计思路:
类型转换、类型断言、动态派发.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 映射存储组),每个组只进行一次访问,组内每个协程会获得对应结果的一个拷贝.
逻辑:
如有错误,请批评指正.
大家好,我是谢伟,是一名程序员.
下面的学习是一个系列,力求从初学者的角度学会go 语言,达到中级程序员水平.
这一系列是我的输出总结,同时我还推出了视频版.正在制作过程.
为写出这些文章,我阅读了网上诸多热门的教程和纸质书籍.内容的实质都是那些,要区分出差异的话,只能表现在具体实例层面.所以,实例我会选取自己在工作中的项目实例抽取出来.希望大家如果觉得本站发布的文章不错,请转发分享给您身边的朋友,您的支持是我们最大的动力.
我们已经研究了:
本节的主题是:接口
接口是 golang 中最值得强调的特性.它让面向对象,内容组织实现非常的方便.
上文中定义了一个 httpClient 的接口,指定了这个接口可以干这些活: Get、Post、Put、Delete
上文中指定了 httpClient 接口,指定了这个接口需要干的活是: Get、Post、Put、Delete , 具体的实现需要靠其他结构体来实现.
一个结构体实现了接口要求的所有的方法(方法的参数和返回值一致),那么就说这个结构体实现了这个接口
上文中的使用: httpClient 屏蔽了 httpImpl 的内部细节,而依然可以使用 Get 方法,去完成任务.
当然接口可以被诸多结构体实现,只需存在接口定义的几种方法即可.
接口和结构体的定义很相似,也可以完成嵌入接口的功能,嵌入的匿名的接口,可以自动的具备被嵌入的接口的方法.
结构体实现 String 方法即可实现结构化输出结构体.
实现Error 方法即可自定义错误类型.
这几个读写接口在好些库中实现了,后续我们再讨论.
Any 类型
空接口在 go 里,可以当成任意类型,意味着,比如你的函数或者方法不知道传入的参数的类型,可以直接定义为 interface{}
类型断言
类型断言的使用场景是:接口类型的变量可以包含任何类型的值.如何判断变量的真实类型?
比如解析一个不知道字段类型的 json, 常常需要使用到类型断言.
可以使用:
ok...idiom
varInterface.(T), varInterface 必须是接口、T 则是具体的实现接口的结构体
switch ..case...
.(type) 只在 switch 语句里才能使用.