↓ 跳过正文
  1. 后端开发/

Golang中context的理解和使用

·2 分钟·
目录
golang

在Go语言中,context包提供了一种在不同的Goroutine之间传递请求范围内的数据、取消信号和截止时间的方法。它主要用于处理与请求相关的操作,例如HTTP请求、数据库查询等。理解和正确使用 context对于编写高效且可维护的Go代码非常重要。

Context的基本概念
#

context.Context是一个接口,定义了一组方法,用于在Goroutine之间传递信息。常用的方法包括:

  • Deadline() (deadline time.Time, ok bool): 返回Context的截止时间。
  • Done() <-chan struct{}: 返回一个通道,当Context被取消或超时时会关闭该通道。
  • Err() error: 返回Context被取消或超时的错误。
  • Value(key interface{}) interface{}: 返回与key关联的值。

创建Context
#

Go提供了几种创建Context的方法:

  • context.Background(): 返回一个空的Context,通常用于主函数、初始化和测试。
  • context.TODO(): 返回一个空的Context,表示尚未确定使用哪种Context。
  • context.WithCancel(parent Context) (ctx Context, cancel CancelFunc): 创建一个可取消的Context。
  • context.WithDeadline(parent Context, d time.Time) (ctx Context, cancel CancelFunc): 创建一个具有截止时间的Context。
  • context.WithTimeout(parent Context, timeout time.Duration) (ctx Context, cancel CancelFunc): 创建一个具有超时的Context。
  • context.WithValue(parent Context, key, val interface{}) Context: 创建一个携带键值对的Context。

使用Context
#

取消操作
#

ctx, cancel := context.WithCancel(context.Background())
defer cancel()
go func() {
    // 模拟一些工作
    time.Sleep(2 * time.Second)
    cancel() // 取消Context
}()
select {
case <-ctx.Done():
    fmt.Println("Context cancelled:", ctx.Err())
}

超时操作
#

ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
defer cancel()
select {
case <-time.After(2 * time.Second):
    fmt.Println("Work completed")
case <-ctx.Done():
    fmt.Println("Context timeout:", ctx.Err())
}

传递值
#

type keyType string
const userKey keyType = "user"
ctx := context.WithValue(context.Background(), userKey, "Alice")
user := ctx.Value(userKey).(string)
fmt.Println("User from context:", user)

总结
#

context包在Go语言中扮演着重要的角色,帮助开发者 管理Goroutine之间的生命周期和数据传递。通过合理使用context,可以提高代码的可读性和可维护性,同时有效地处理取消和超时操作。在实际开发中,建议始终将 context作为函数的第一个参数传递,以确保上下文信息能够正确传递。

叶知秋
作者
叶知秋
写后端的,日常和 Java、Go、数据库、消息队列打交道,也折腾网络和自托管。这里记录实践中搞明白的东西。

相关文章