Golang中Context和defer的用法探讨
Golang中Context和defer的用法探讨
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
_, err := m.DB.Exec(ctx, stmt, email, username, password)
如果包含函数被上下文取消,defer cancel() 会返回什么给调用者?
defer func(ctx context.CancelFunc) error {
err := errors.New("timeout")
ctx()
}(cancel
或者这是我唯一的选择吗?
更多关于Golang中Context和defer的用法探讨的实战教程也可以访问 https://www.itying.com/category-94-b0.html
2 回复
由函数决定返回什么。通常是 context.Canceled 或包装了 context.Canceled 的内容。
更多关于Golang中Context和defer的用法探讨的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
在Go中,defer cancel() 不会向调用者返回任何值,它只是确保在函数退出时调用取消函数。当上下文超时或取消时,m.DB.Exec 会返回一个错误(通常是 context.DeadlineExceeded 或 context.Canceled),但 defer cancel() 本身没有返回值。
您的第二个代码片段有语法错误,但意图可能是想在取消时返回自定义错误。实际上,您不需要通过 defer 来返回错误,因为数据库操作会直接返回错误。以下是正确的示例:
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
_, err := m.DB.Exec(ctx, stmt, email, username, password)
if err != nil {
// 这里 err 可能是 context.DeadlineExceeded 或其他错误
return err
}
如果您想在取消时执行额外操作(如记录日志),可以这样做:
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer func() {
cancel()
// 可以在这里添加其他清理代码,但无法通过 defer 返回错误给调用者
}()
_, err := m.DB.Exec(ctx, stmt, email, username, password)
if err != nil {
// 处理错误
return err
}
注意:defer 语句中的函数不能直接向外部函数返回值,但可以修改命名返回值或执行副作用操作。对于上下文取消,错误处理应通过操作返回的 err 进行。

