context 包用于做并发控制,它可以携带各种上下文,一般来说只要涉及到并发的场合,都会使用 context。context 一般作为函数的第一个参数。
# 继承
在搞懂 context 包之前,首先需要搞懂 golang 里的继承,这是 context 可以一层一层携带信息的基础。
package main | |
import ( | |
"errors" | |
"fmt" | |
"log" | |
) | |
type runner interface { | |
name(string) error | |
run() | |
stop() | |
} | |
type car struct{} | |
func (car) name(n string) error { | |
return errors.New("cant find name") | |
} | |
func (car) run() { | |
fmt.Println("running") | |
} | |
func (car) stop() { | |
fmt.Println("stoped") | |
} | |
type bus struct { | |
runner | |
busname string | |
} | |
func (b bus) name(n string) error { | |
if n == b.busname { | |
fmt.Println("find name") | |
return nil | |
} | |
return b.runner.name(n) | |
} | |
func main() { | |
c := car{} | |
var b bus = bus{ | |
c, | |
"bus", | |
} | |
g := bus{ | |
b, | |
"weilai", | |
} | |
t := bus{ | |
g, | |
"tesla", | |
} | |
err := t.name("buss") | |
if err != nil{ | |
log.Println(err) | |
} | |
} |
我在这里定义了一个借口 runner,两个类 car 和 bus,其中 car 只是单纯实现了 runner 接口,但是 bus 还多了一个 busname 字段,以及继承了 runner 接口。
type bus struct { | |
runner | |
busname string | |
} |
bus 继承了 runner 接口,那么 bus 也就默认实现了 runner 接口,可以直接 bus.run (),调用函数。
那么 bus 既然实现了 runner 接口,那么就可以把实例化的 bus 结构体作为 runner 给新的 bus 结构体初始化。可以看到我用 bus 结构体 b 初始化了 g,再用 g 初始化了 t。
因此,如果要查询一个 busname 是否出现在我们的初始化过程里,比如查询 buss
是 b, g, t
的名字。
func (b bus) name(n string) error { | |
if n == b.busname { | |
fmt.Println("find name") | |
return nil | |
} | |
return b.runner.name(n) | |
} | |
func (car) name(n string) error { | |
return errors.New("cant find name") | |
} |
这里 car 是没有名字的,只有 bus 有名字,bus 会层层调用,直到找到 name。
注意,如果用:
t.runner.runner |
是会报错的,因为 runner 内没有实现 runner 字段。
这里有一篇关于 context 的文章;
https://mp.weixin.qq.com/s/_5gBIwvtXKJME7AV2W2bqQ
基本上把 context 讲明白了。
# context
context.TODO 和 context.Background 是创建 context 的跟节点,传入下面这些函数的初始化 context。由 TODO 和 BackGround 创建的 context 是 emptycontext,所以这两个函数作用一致。
func WithCancel(parent Context) (ctx Context, cancel CancelFunc) | |
func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc) | |
func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) | |
func WithValue(parent Context, key, val interface{}) Context |
WithCancel 创建 cancelcontext,用于取消,Valuecontext 用于传递 value,timeout 用于传递超时的上下文。
不懂就去看 https://mp.weixin.qq.com/s/_5gBIwvtXKJME7AV2W2bqQ 就行了。