1. Home
  2. Docs
  3. golang
  4. 内置库(包-package)
  5. context

context

>>>原文 | 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的用户应该为键定义自己的类型。为了避免在分配给一个接口{}时进行分配,上下文键通常具有具体的结构{}类型。或者,导出的上下文关键变量的静态类型应该是一个指针或接口。

扩展阅读

编程中什么是「Context(上下文)」?

上下文 Context

Go 语言解密之上下文 Context

Tags
Was this article helpful to you? Yes No

How can we help?