go - 为什么不只是在方法 header.clone 中为目标赋值
问题描述
正式版我的问题是“sv”的作用是什么
func (h Header) Clone() Header {
if h == nil {
return nil
}
// Find total number of values.
nv := 0
for _, vv := range h {
nv += len(vv)
}
sv := make([]string, nv) // shared backing array for headers' values
h2 := make(Header, len(h))
for k, vv := range h {
n := copy(sv, vv)
h2[k] = sv[:n:n]
sv = sv[n:]
}
return h2
}
为什么不把它写成这样,只是将值分配给 h2 而不是创建一个切片
for k, vv := range h {
// changed here
h2[k] = vv
}
解决方案
它看起来像Header
一个map[string][]string
,(也许是 http.Header?)。如果它按照您的建议进行,那么新Header
的将是地图的浅表副本,其中包含来自 source 的原始切片Header
。如果修改了这些切片的后备数组的内容,则复制的标头也将被修改。例如:
s:=make([]string,0,10)
s=append(s,"a")
header[key]=s
h2:=header.Clone()
s=append(s,"b")
// Here, both header[key] and h2[key] has two elements, "a" and "b"
防止这种情况,Clone
正在做一个深拷贝,其中每个[]string
也被复制。那将需要len(h)
字符串切片分配,每个键一个。相反,该算法使用一个分配,一个包含原始标头的所有字符串的单个共享字符串切片。
该算法首先计算标题中包含的字符串数量,并分配该大小的字符串切片。在第二个 for 循环中,它将字符串从键的值复制到共享字符串切片,使用该共享切片数组创建切片并将其设置为键的值,然后更新共享切片以指向下一个可用的空槽。最后,它是一个具有单一内存分配的深拷贝,而不是len(h)
.
推荐阅读
- java - 如何从字符串中检索值?
- julia - 无法读取 csv 文件:“没有匹配 Parsers.Options 的方法”
- java - Nashorn 将compiledsript 放入引擎范围
- mule - 如何在 Tranform 中对变量使用 encodeURI
- python - Python Qt SpinBox 在失焦时更新
- arrays - 使用 Google Colab 时如何保存 np.array 的结果以供将来使用
- logging - Spring Kafka监听器方法-记录输入记录
- c - 为什么 printf() 只在 WSL2(Ubuntu) 上延迟执行的循环之后执行?
- javascript - 带有按钮的Jquery Onclick不显示窗口
- asp.net-core - AspNetCore 无法在 POST 操作中获取有效负载的值