其他
在 Go 中使用 context.Context…
适用于 Go 中处理 context.Context 的函数签名放置、取消与超时传播,以及决定请求作用域数据应放参数还是 context.Value。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 48/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 85/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 57/100 ×0.15
适用场景
在 Go 中使用 context.Con通用
解决思路
- 当需要派生 context、检查取消、处理 HTTP request context 或使用 typed context-value keys 时,阅读 references/PATTERNS.md。
- 使用 Context 的函数应将 context.Context 作为第一个参数,例如 `func F(ctx context.Context, /* other arguments */) error`、`func ProcessRequest(ctx context.Context, req *Request) (*Response, error)`;这是 Go 的强约定,使 context 流向可见且跨代码库一致。
- 不要在 struct 中添加 Context 成员;改为在每个需要它的方法上传入 ctx 参数。反例:`type Worker struct { ctx context.Context }`;正例:`type Worker struct{ /* ... */ }` 与 `func (w *Worker) Process(ctx context.Context) error`,这样生命周期清晰。
- 例外:方法签名必须匹配标准库或第三方库的接口时,可能需要绕过“不把 Context 存入 struct”的限制。
- 不要创建自定义 Context 类型,也不要在函数签名中使用 context.Context 以外的接口。反例:`type MyContext interface { context.Context; GetUserID() string }`;正例:`func Process(ctx context.Context) error { userID := GetUserID(ctx) }`。
- 放置应用数据时首选函数参数,因为它最显式且类型安全。
- 其次使用 receiver,适合属于该类型的数据。
- 再次使用全局变量,仅用于真正的全局配置且谨慎使用。
- 最后才使用 context value,且仅用于请求作用域数据。
- context value 适合请求 ID 和 trace ID。
- context value 适合随请求流转的认证/授权信息。
- context value 适合 deadline 和取消信号。
- context value 不适合可选函数参数。
- context value 不适合可以显式传递的数据。
- context value 不适合不随请求变化的配置。
- 派生 context 后立即 `defer cancel()`:`ctx, cancel := context.WithTimeout(ctx, 5*time.Second); defer cancel()`。
- 检查取消:`select { case <-ctx.Done(): return ctx.Err(); default: // Do work }`。
- context 是不可变的:可以安全地把同一个 ctx 传给多个共享相同 deadline 和取消信号的并发调用。
- 当使用 context 进行 goroutine 取消、基于 select 的超时或 errgroup 时,查看 go-concurrency。
- 当决定如何包装或返回 ctx.Err() 取消错误时,查看 go-error-handling。
- 当设计同时接受 context 和接口的 API 时,查看 go-interfaces。
- 当将 logger 注入 context 或向结构化日志输出添加请求 ID 时,查看 go-logging。
适用边界 · 注意事项
- 不适用于 goroutine 生命周期管理或 sync 原语;这些应看 go-concurrency。
- 当方法签名必须匹配标准库或第三方库接口时,“不要将 Context 存入 struct”的强规则可能不适用,需要按接口约束处理。
- 不要把 context value 用于可选函数参数、可显式传递的数据或不随请求变化的配置。