Context简介&目录
简介
以下来自官方文档的翻译:
context
包定义了 Context
类型,用于跨越 API 边界和进程传递截止时间、取消信号以及其他与请求相关的值。
服务器接收到的请求应该创建一个 Context
,而发往服务器的调用应该接受一个 Context
。在它们之间的函数调用链必须传播 Context
,并可以选择用 WithCancel
、WithDeadline
、WithTimeout
或 WithValue
创建的派生 Context
进行替换。当一个 Context
被取消时,所有从它派生的 Context
也会被取消。
WithCancel
、WithDeadline
和 WithTimeout
函数接收一个 Context
(即父上下文)并返回一个派生的 Context
(即子上下文)以及一个 CancelFunc
。调用 CancelFunc
会取消子上下文及其派生的上下文,移除父上下文对子上下文的引用,并停止任何相关的计时器。如果未调用 CancelFunc
,则会导致子上下文及其派生上下文被泄漏,直到父上下文被取消或计时器触发。go vet
工具会检查所有控制流路径上是否正确使用了 CancelFunc
。
WithCancelCause
函数返回一个 CancelCauseFunc
,它接收一个错误并将其记录为取消原因。在已取消的上下文或其派生上下文上调用 Cause
可以检索取消原因。如果未指定原因,则 Cause(ctx)
返回与 ctx.Err()
相同的值。
使用 Context
的程序应遵循以下规则,以保持接口在各个包之间的一致性,并使静态分析工具能够检查上下文传播:
-
不要在结构体类型中存储
Context
;相反,应显式地将Context
作为参数传递给每个需要它的函数。Context
应为第一个参数,通常命名为ctx
:func DoSomething(ctx context.Context, arg Arg) error { // ... 使用 ctx ... }
-
不要传递一个空的
Context
,即使某个函数允许这样做。如果不确定要使用哪个Context
,可以传递context.TODO
。 -
仅将
context
的值用于与请求相关的数据传递,这些数据会跨越进程和 API,而不是用于传递函数的可选参数。 -
相同的
Context
可以传递给在不同 goroutine 中运行的函数;Context
是线程安全的,可以被多个 goroutine 同时使用。
目录
本专栏将按照Context、emptyCtx、cancelCtx、timerCtx、valueCtx的结构去解析Context标准库,讲解清楚每一个接口或者类型的组成、方法与调用,确保可以从源码层面理解Context标准库。
Context接口&emptyCtx类型(包括background和todo):Golang-Context标准库源码深扒-Context接口与emptyCtx类型
cancelCtx类型(用于WithCancel) :Golang-Context标准库源码深扒-cancelCtx类型
timerCtx类型(用于WithDeadline、WithTimeout):Golang-Context标准库源码深扒-timerCtx类型
valueCtx类型(用于WithValue) :Golang-Context标准库源码深扒-valueCtx类型