>>>原文 | by DeepL 翻译
Overview
包context定义了Context类型,它跨越API边界和进程之间携带截止日期、取消信号和其他请求范围的值。
对服务器的传入请求应该创建一个Context,而对服务器的传出调用应该接受一个Context。它们之间的函数调用链必须传播该上下文,可以选择用使用WithCancel、WithDeadline、WithTimeout或WithValue创建的派生上下文取代它。当一个上下文被取消时,所有从它派生的上下文也会被取消。
WithCancel、WithDeadline和WithTimeout函数接收一个上下文(父级)并返回一个派生的上下文(子级)和一个CancelFunc。调用CancelFunc可以取消子节点及其子节点,删除父节点对子节点的引用,并停止任何相关的定时器。如果不调用CancelFunc,就会泄露子代及其子代,直到父代被取消或定时器被触发。go vet工具检查所有控制流路径上是否使用了CancelFuncs。
使用Contexts的程序应该遵循这些规则,以保持不同软件包之间的接口一致,并使静态分析工具能够检查上下文传播。
不要将 Context 存储在结构类型中;相反,应将 Context 明确地传递给需要它的每个函数。上下文应该是第一个参数,通常命名为ctx。
func DoSomething(ctx context.Context, arg Arg) error {
// ... use ctx ...
}
不要传递nil Context,即使一个函数允许这样做。如果你不确定要使用哪个Context,请传递context.TODO。
仅在传递进程和API的请求范围数据时使用context Values,而不是在向函数传递可选参数时使用。
同一个Context可以被传递给在不同goroutine中运行的函数;Context在多个goroutine中同时使用是安全的。
关于使用Contexts的服务器的示例代码,见https://blog.golang.org/context。
Variables
var Canceled = errors.New("context canceled")
Canceled是Context.Err在上下文被取消时返回的错误。
var DeadlineExceeded error = deadlineExceededError{}
DeadlineExceeded是Context.Err在上下文的最后期限过后返回的错误。
Functions
func WithCancel
func WithCancel(parent Context) (ctx Context, cancel CancelFunc)
WithCancel返回一个带有新的Done通道的父类副本。当返回的cancel函数被调用时,或者当父级上下文的Done通道被关闭时,返回的上下文的Done通道会被关闭,以先发生的为准。
取消这个上下文会释放与之相关的资源,所以代码应该在这个上下文中运行的操作完成后立即调用取消。
func WithDeadline
func WithDeadline(parent Context, d time.Time) (Context, CancelFunc)
WithDeadline返回一个父级上下文的副本,其最后期限调整为不晚于d。如果父级上下文的最后期限已经早于d,WithDeadline(parent, d)在语义上等同于parent。返回的上下文的Done通道在最后期限到期时、返回的cancel函数被调用时、或者父级上下文的Done通道被关闭时(以先发生者为准)被关闭。
取消这个上下文会释放与之相关的资源,所以代码应该在这个上下文中运行的操作完成后立即调用取消。
func WithTimeout
func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc)
WithTimeout返回WithDeadline(parent, time.Now().Add(timeout))。
取消这个上下文会释放与之相关的资源,所以代码应该在这个上下文中运行的操作完成后立即调用取消。
Types
type CancelFunc
type CancelFunc func()
CancelFunc告诉一个操作要放弃它的工作。CancelFunc并不等待工作的停止。一个CancelFunc可以被多个goroutine同时调用。在第一次调用之后,对CancelFunc的后续调用不做任何事情。
type Context
Context携带一个截止日期,一个取消信号,以及其他跨越API边界的值。
Context的方法可以被多个goroutine同时调用。
func Background
func Background() Context
Background返回一个非零的空的Context。它永远不会被取消,没有值,也没有截止日期。它通常被主函数、初始化和测试使用,并作为传入请求的顶层上下文。
func TODO
func TODO() Context
TODO返回一个非零的空的Context。当不清楚应该使用哪个Context或者它还不可用时(因为周围的函数还没有被扩展到接受Context参数),代码应该使用context.TODO。
func WithValue
func WithValue(parent Context, key, val interface{}) Context
WithValue返回一个父类的副本,其中与key相关的值是val。
使用context Values只能用于传输进程和API的请求范围的数据,不能用于向函数传递可选参数。
提供的键必须是可比较的,并且不应该是字符串类型或任何其他内置类型,以避免使用上下文的包之间发生碰撞。WithValue的用户应该为键定义自己的类型。为了避免在分配给一个接口{}时进行分配,上下文键通常具有具体的结构{}类型。或者,导出的上下文关键变量的静态类型应该是一个指针或接口。