2 回答
TA贡献1839条经验 获得超15个赞
所以这里有一些事情在起作用。我强烈推荐 goblog 对此的解释:https ://blog.golang.org/slices (转到标记为容量的部分)。此外,只是一点(微小的)语义,但那些实际上是切片,而不是数组:)
切入正题,当您第一次声明切片时,len 为 3,容量为 10。没问题。但是随后您重新声明了 myArray,并将其设置为 []int{1,2,3}。也没有问题,这是有效的。
当您希望之前的 len/cap 保持不变时,问题就出现了;您的切片只是指向内存中某个空间的指针。所以你现在已经改变了你的底层指针(参见 goblog)。切片的容量和长度现在也发生了变化(默认情况下 - 再次参见 goblog)。如果要添加更多元素,您可以看到 len/cap 的相同变化:
myArray := make([]int, 3, 10)
fmt.Println("len:"len(myArray),", cap:",cap(myArray)) // len: 3 cap: 10
myArray := []int{1, 2, 3}
fmt.Println("len:", len(myArray), "cap:", cap(myArray)) // len: 3 cap: 3
myArray = append(myArray, 4)
fmt.Println("len:", len(myArray), "cap:", cap(myArray)) // len: 4 cap: 8; automatically increases the cap
TA贡献1871条经验 获得超8个赞
我相信您会得到这个结果,因为在第一个示例中您声明了一个长度为 3 且上限为 10 的切片。但是,在以下语句中,您将一个完全不同的切片分配给该变量。由于您分配的切片是使用“复合文字”语法声明/初始化的,并且它只有 3 个项目,这就是它初始化的容量。在第二个示例中,您为使用 make 创建的切片的每个索引分配值,同时保留长度和容量属性。
尝试给出更多说明......在 C# 或 Java 或 C++ 中,这就像做这样的事情;
List<string> myStrings = new List<string>();
myStrings.Add("A string");
myStrings = new List<string>();
正如您可能假设的那样,在将新列表分配给 myStrings 变量后,旧列表将丢失。因此,给出简单的答案,您不仅要覆盖上限,还要覆盖整个切片。您在分配中拥有的值会覆盖它,导致创建一个上限为 3 的切片,这就是您获得该结果的原因。
- 2 回答
- 0 关注
- 127 浏览
添加回答
举报