为了账号安全,请及时绑定邮箱和手机立即绑定

为什么不只是在方法 header.clone 中为目标赋值

为什么不只是在方法 header.clone 中为目标赋值

Go
当年话下 2022-05-05 18:01:33
正式版我的问题是“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    }
查看完整描述

1 回答

?
一只甜甜圈

TA贡献1836条经验 获得超5个赞

它看起来像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).


查看完整回答
反对 回复 2022-05-05
  • 1 回答
  • 0 关注
  • 116 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信