如何扩充 ResponseWriter 的 Header() 返回的地图

How to augment the map returned by a ResponseWriter's Header()

所以我确定我想在这里作弊,但是 ResponseWriter 文档有一个方法 'Header()',它正在使用 returns Header object。 https://pkg.go.dev/net/http#ResponseWriter.Header

现在我从其他地方得到一个 http.Response,我想将所有 header 复制到我的 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

显然这两个都没有意义,根本不起作用,但希望传达我正在尝试做的事情的想法。

任何人都可以解释为什么我正在尝试做的事情不起作用吗?或者也许确实如此,但我只是没有看到这样做的方法?

你不能。

w 是一个 http.ResponseWriter,它是一种接口类型 - 因此只有方法,没有可直接访问的字段。如您所知,它有一种获取底层 Header 映射的方法。

但是,它没有“Setter”方法来替换地图。因此,复制 header 值的唯一方法是像您引用的循环那样手动复制。

您不必自己编写该循环。 Go 1.18 看到添加包 golang.org/x/exp/maps, which provides a convenient Copy function:

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)

但是请注意,由于响应可以包含 duplicate headers,因此 maps.Copy 的使用并不完全等同于您的循环:

for k := range resp.Header 
    w.Header().Add(k, resp.Header.Get(k))
}

maps.Copy 相反,您的循环仅检索 first header 对应于 [=24= 中每个 header 名称的值].