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

数组上限被覆盖

数组上限被覆盖

Go
拉丁的传说 2022-01-04 14:04:07
你能建议吗?使用 make([]int,len,cap),GO 是否允许在声明的同时进行数组初始化?myArray := make([]int, 3, 10){1,2,3}在下面的情况下,我看到 cap(myArray) 已更改为 len(myArray) 。背后的根本是什么?<ex>       myArray := make([]int, 3, 10)       myArray = []int{1,2,3}       fmt.Println("len:"len(myArray),", cap:",cap(myArray))长度:3,上限:3为什么我声明时 cap(myArray) 是 3 而不是 10?我直接初始化了单个元素。而且,它按我的意愿工作<ex>       myArray := make([]int, 3, 10)       myArray[0] = 1       myArray[1] = 2       myArray[2] = 3       fmt.Println("len:"len(myArray),", cap:",cap(myArray))长度:3,上限:10
查看完整描述

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



查看完整回答
反对 回复 2022-01-04
?
ITMISS

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 的切片,这就是您获得该结果的原因。


查看完整回答
反对 回复 2022-01-04
  • 2 回答
  • 0 关注
  • 127 浏览
慕课专栏
更多

添加回答

举报

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