栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

Go何时分配新的支持数组进行切片?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Go何时分配新的支持数组进行切片?

答案很简单:

append()
如果要添加的元素不适合当前容量,则分配一个新的支持数组(并复制当前内容)。正式地:

if len(s) + len(newElements) > cap(s) {    // Allocate new backing array    // copy content (s) over to new array} else {    // Just resize existing slice}// append (copy) newElements

因此,例如,如果len = 2,cap = 4,则可以追加2个元素,无需分配。

如果len = 2,cap = 4,并添加3个元素,则len + 3> cap,因此将分配一个新的支持数组(其容量将大于len +
3,考虑到未来的增长,但其长度将是2 + 3 = 5)。

解释你的第一个例子

在第一个示例中,您声明一个切片变量,其长度和容量为0。

var a []intfmt.Println(len(a), cap(a)) // Prints 0 0

当您进行第一次追加时,将分配一个新数组:

a = append(a, 0)fmt.Println(len(a), cap(a)) // Prints 1 2

当您执行另一个追加时,它适合容量,因此没有分配:

fmt.Println(len(a), cap(a)) // Prints 1 2b := append(a, 1)fmt.Println(len(b), cap(b)) // Prints 2 2

但是这次您将结果切片存储在中

b
,而不是中
a
。因此,如果对进行第3次追加
a
,则仍然具有length = 1和cap =
2,因此将另一个元素追加到
a
不需要分配:

fmt.Println(len(a), cap(a)) // Prints 1 2c := append(a, 2)fmt.Println(len(c), cap(c)) // Prints 2 2

所以除第一追加,所有其他附加不需要分配,因此第一分配背衬阵列用于所有

a
b
c
切片,因此它们第一元件的地址将是相同的。这就是您所看到的。

解释第二个例子

再次创建一个空切片(len = 0,cap = 0)。

然后执行第一个附加操作:2个元素:

a = append(a, 0, 9)fmt.Println(len(a), cap(a)) // Prints 2 2

这将分配一个新的数组,其长度为2,因此切片的长度和容量均为2。

然后执行第二次追加:

d := append(a, 1, 2)fmt.Println(len(d), cap(d)) // Prints 4 4

由于没有更多元素的空间,因此将分配一个新数组。但是您将指向此新数组的切片存储在中

d
,而不是中
a
a
仍然指向旧数组。

然后,执行第三个附加操作,但是要附加

a
(指向旧数组):

fmt.Println(len(a), cap(a)) // Prints 2 2e := append(a, 3, 4)fmt.Println(len(e), cap(e)) // Prints 4 4

同样,数组

a
不能容纳更多元素,因此分配了一个新数组,将其存储在中
e

因此

d
e
它们具有不同的支持数组,并且将附加到与“另一个”切片共享支持数组的任何切片都不会(无法)更改此“另一个”切片。因此,结果是您
d
两次看到相同的地址,而看到的是不同的地址
e



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/394638.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号