【问题标题】:Understanding slice assignment in Go理解 Go 中的切片分配
【发布时间】:2017-07-11 09:42:28
【问题描述】:

在下面的代码 sn-p 中,if 块后面的行到底在做什么

slice = slice[0:l+len(data)]?

func Append(slice, data []byte) []byte {
    l := len(slice)
    if l + len(data) > cap(slice) {  // reallocate
        // Allocate double what's needed, for future growth.
        newSlice := make([]byte, (l+len(data))*2)
        // The copy function is predeclared and works for any slice type.
        copy(newSlice, slice)
        slice = newSlice
    }
    slice = slice[0:l+len(data)]  // <-- What is this doing ?
    for i, c := range data {
        slice[l+i] = c
    }
    return slice
}

【问题讨论】:

    标签: go


    【解决方案1】:

    我猜

    slice = slice[0:l+len(data)] 
    

    更改slice 的长度,因此您可以添加新元素。

    只要有足够的容量,您可以通过重新切片来扩展切片的长度。

    reference

    【讨论】:

    • 不,切片的容量被其正上方的 3 个语句扩展。它唯一做的就是将原始值和“0”重新分配给额外的位置,但这也是一种浪费,因为 Go 已经填充了它们。这也是第二次浪费,因为它也重新定义了所有这些值之后的循环。所以,这条线根本没有用。
    • 请看我的回答以获得详细解释。
    【解决方案2】:

    只是扩展len(slice),所以可以追加数据,去掉这条语句,会出现slice out of index...另外,copy返回min len(src)和len(dst),所以在执行@ 987654321@,len(slice) 为 0

    【讨论】:

      【解决方案3】:

      只是发布此答案以供将来参考。

      那条线没有用。切片的容量由其上方的语句扩展。

              // Allocate double what's needed, for future growth.
              newSlice := make([]byte, (l+len(data))*2)
              // The copy function is predeclared and works for any slice type.
              copy(newSlice, slice)
              slice = newSlice
      

      第一行创建了一个更大的切片,称为“newSlice”。
      在第二个中,“slice”将其内容复制到“newSlice”。
      然后,“newSlice”有点克隆回“slice”。

      是的,Go 确实对这件事感到奇怪,因为内容也没有被复制,但是“slice”现在与“newSlice”具有相同的容量。但它不像 C 中的“指针分配”,因为我们仍然有两个不同的切片实例,并且其中一个实例发生的事情不会影响另一个。请注意使用赋值运算符“=”而不是短变量声明运算符“:=”,如this answer in SO中所述

      实际上所做的是将原始“slice”值和“0”分配给“newSlice”额外位置,但这也是一种浪费,因为Go已经在@987654324中将它们初始化为“0” @ 声明。

      这也是第二次浪费,因为在它重新定义了所有这些位置以及“数据”中的其余内容之后的循环。这个link 可能有助于理解循环的含义。

      所以,这条线根本没有用,你应该删除它。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-05-12
        • 2019-08-09
        • 2019-12-22
        • 1970-01-01
        • 2014-01-31
        • 1970-01-01
        • 2022-01-25
        相关资源
        最近更新 更多