英文:
How to augment the map returned by a ResponseWriter's Header()
问题
我确定我在这里尝试作弊,但是ResponseWriter文档中有一个名为'Header()'的方法,它返回它正在使用的Header对象。
https://pkg.go.dev/net/http#ResponseWriter.Header
现在我从其他地方获取了一个http.Response,并且我想将该响应的所有标头复制到我的ResponseWriter中。
现在,我可以使用类似这样的for循环:
for k := range resp.Header
w.Header().Add(k, resp.Header.Get(k))
}
从逻辑上讲,我也认为只需将ResponseWriter的header引用更改为Response的header即可,但是似乎ResponseWriter类型正在积极阻止我这样做。
脑海中浮现出一些愚蠢的想法
w.Header() = resp.Header
或者
rwHeader := w.Header()
rwHeader = resp.Header
显然,这两种方法都没有意义,根本不起作用,但希望能传达我尝试做的事情的想法。
有人能解释一下为什么我尝试的方法不起作用吗?或者也许它确实起作用,只是我没有找到方法?
英文:
So I'm sure I'm trying to cheat here, but the ResponseWriter docs has a method 'Header()' which returns the Header object it's using.
https://pkg.go.dev/net/http#ResponseWriter.Header
Now I'm getting a http.Response from somewhere else, and I want to copy across all the headers from that into my ResponseWriter.
Now, I could use a for loop like this:
for k := range resp.Header
w.Header().Add(k, resp.Header.Get(k))
}
Logically, it also made sense for me to just change the reference from the ResponseWriter's header, to the Response's header, however it seems like the ResponseWriter type is actively trying to stop me from doing that.
Something stupid like this comes to mind
w.Header() = resp.Header
Or
rwHeader := w.Header()
rwHeader = resp.Header
Obviously both of these make no sense and do not work at all, but hopefully conveys the idea of what I'm trying to do.
Can anyone offer an explanation of why what I'm trying to do doesn't work? Or maybe it does and I'm just not seeing the way to do it?
答案1
得分: 3
你不需要自己编写那个循环。Go 1.18 中引入了 golang.org/x/exp/maps
包,它提供了一个方便的 Copy
函数:
func Copy[M ~map[K]V, K comparable, V any](dst, src M)
Copy
函数将 src
中的所有键值对复制并添加到 dst
中。当 src
中的键在 dst
中已经存在时,dst
中的值将被 src
中的键关联的值覆盖。
import "golang.org/x/exp/maps"
// ...
maps.Copy(w.Header(), resp.Header)
然而,请注意,由于响应可以包含重复的头部,使用 maps.Copy
并不完全等同于你的循环:
for k := range resp.Header
w.Header().Add(k, resp.Header.Get(k))
}
与 maps.Copy
不同,你的循环只检索与 resp.Header
中每个头部名称对应的第一个头部值。
英文:
You don't have to write that loop yourself. Go 1.18 saw the addition of package golang.org/x/exp/maps
, which provides a convenient Copy
function:
> go
> func Copy[M ~map[K]V, K comparable, V any](dst, src M)
>
>
> Copy
copies all key/value pairs in src
adding them to dst
. When
> a key in src
is already present in dst
, the value in dst
will be
> overwritten by the value associated with the key in src
.
import "golang.org/x/exp/maps"
// ...
maps.Copy(w.Header(), resp.Header)
However, note that, because a response can contain duplicate headers, the use of maps.Copy
isn't exactly equivalent to your loop:
for k := range resp.Header
w.Header().Add(k, resp.Header.Get(k))
}
Contrary to maps.Copy
, your loop retrieves only the first header value corresponding to each header name present in resp.Header
.
答案2
得分: 2
你不能这样做。
w
是一个 http.ResponseWriter,它是一个接口类型,只有方法而没有直接可访问的字段。它有一个方法可以获取底层的 Header
映射。
然而,它没有一个“Setter”方法来替换映射。所以唯一的方法是手动复制头部值,就像你引用的循环所做的那样。
英文:
You can't.
w
is an http.ResponseWriter which is an interface type - so only has methods and no directly accessible fields. It has, as you know, a method to get the underlying Header
map.
It does not, however, have a "Setter" method to replace the map. So the only way to copy over header values is by hand like your cited loop does.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论