以下摘自http/request.go
第290行的源代码:
// WithContext returns a shallow copy of r with its context changed
// to ctx. The provided ctx must be non-nil.
func (r *Request) WithContext(ctx context.Context) *Request {
if ctx == nil {
panic("nil context")
}
r2 := new(Request) //
*r2 = *r // strange gymnastics
r2.ctx = ctx //
return r2
}
我看了一个小时试图理解最后4行。为什么体操?它不仅仅意味着以下内容:
r.ctx = ctx
return r
或者我错过了什么?
答案 0 :(得分:6)
让我们检查一下有问题的行:
r2 := new(Request)
这是short variable declaration,创建r2
变量,并使用右侧表达式的值对其进行初始化,右侧表达式是对内置new()
函数的调用,为给定类型分配内存,并返回指向它的指针(作为该类型的zero value)。
*r2 = *r
此行将{{1>}的值指向分配给r
的值指向。请注意,这不会指定指针值,而是指向值。由于指向的值是类型为r2
的结构,因此赋值会复制字段的值。
Request
由于r2.ctx = ctx
是指向结构的指针,因此这是r2
的简写,它将给定的上下文值分配给值的(*r2).ctx = ctx
字段(类型{{1} } {}由ctx
指出。
Context
然后返回此r2
指针。请注意,return r2
是一个与r2
不同的指针,指向的值是与r2
指向的不同且独立的请求。
如果你愿意的话
r
它会将上下文分配给r
指向的r.ctx = ctx
return r
字段,并返回相同的ctx
指针。返回的值与r
的值相同,因此r
和返回的值都指向相同的r
值,并且两者都有新的r
值。原始代码不会修改原始请求的Request
(调用Context
方法的请求)。