为什么在某些情况下会存在 *Request.Context() 并返回 context.Background()?

huangapple go评论92阅读模式
英文:

Why *Request.Context() exists and returns a context.Background() in some cases?

问题

请帮助我理解*Request.Context函数:

// Context返回请求的上下文。要更改上下文,请使用WithContext。
//
// 返回的上下文始终非nil;它默认为后台上下文。
//
// 对于出站客户端请求,上下文控制取消。
//
// 对于传入的服务器请求,当客户端的连接关闭、请求被取消(使用HTTP/2)或ServeHTTP方法返回时,上下文被取消。
func (r *Request) Context() context.Context {
	if r.ctx != nil {
		return r.ctx
	}
	return context.Background()
}
  1. 为什么我们需要这个函数而不是在*Request上使用公共属性?它只是为了封装,以便没有人可以更改它,使其实际上是只读的吗?

  2. 什么情况下会发生r.ctx != nil并返回context.Background()?难道不是每个HTTP请求在接收到时都保证有一个上下文吗?如果context.Background()永远不会因超时或取消而变为“完成”,那么它的用途是什么?基本上,为什么不使用以下代码?

func (r *Request) Context() context.Context {
	return r.ctx
}
英文:

Please help me to understand the *Request.Context function:

// Context returns the request's context. To change the context, use
// WithContext.
//
// The returned context is always non-nil; it defaults to the
// background context.
//
// For outgoing client requests, the context controls cancellation.
//
// For incoming server requests, the context is canceled when the
// client's connection closes, the request is canceled (with HTTP/2),
// or when the ServeHTTP method returns.
func (r *Request) Context() context.Context {
	if r.ctx != nil {
		return r.ctx
	}
	return context.Background()
}
  1. Why do we need this function instead of using a public property on *Request? Is it just for encapsulation so that nobody can change it, making it effectively read-only?

  2. When can it happen that the r.ctx != nil and context.Background() is returned? Isn't every http request guaranteed to have a context the moment it is received? And what is the use of context.Background() if it never becomes 'done' due to timeout or cancellation? Basically, why not this instead?

func (r *Request) Context() context.Context {
	return r.ctx
}

答案1

得分: 2

  1. 是的,这是为了封装。使用WithContextNewReqeustWithContext来创建一个带有所选上下文的请求。

  2. r := &http.Request{} 创建一个没有上下文的请求。确保返回一个非nil值是为了方便调用者。当没有指定其他上下文时,背景上下文是一个合适的默认值。

英文:
  1. Yes, it is for encapsulation. Use WithContext or NewReqeustWithContext to create a request with the context of your choice.

  2. r := &http.Request{} creates a request with no context. Ensuring a non-nil return value is a convenience for the caller. The background context is a suitable default when no other context is specified.

huangapple
  • 本文由 发表于 2021年10月21日 09:08:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/69654678.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定