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 是否出现在我们的初始化过程里,比如查询 bussb, 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

image-20220118184015550

WithCancel 创建 cancelcontext,用于取消,Valuecontext 用于传递 value,timeout 用于传递超时的上下文。

不懂就去看 https://mp.weixin.qq.com/s/_5gBIwvtXKJME7AV2W2bqQ 就行了。

更新于

请我喝[茶]~( ̄▽ ̄)~*

Kalice 微信支付

微信支付

Kalice 支付宝

支付宝