gpt4 book ai didi

Golang 将项目附加到 slice

转载 作者:IT老高 更新时间:2023-10-28 12:58:08 24 4
gpt4 key购买 nike

为什么 slice a 保持不变? append() 会生成新 slice 吗?

package main

import (
"fmt"
)

var a = make([]int, 7, 8)

func Test(slice []int) {
slice = append(slice, 100)
fmt.Println(slice)
}

func main() {
for i := 0; i < 7; i++ {
a[i] = i
}

Test(a)
fmt.Println(a)
}

输出:

[0 1 2 3 4 5 6 100]
[0 1 2 3 4 5 6]

最佳答案

在您的示例中,Test 函数的 slice 参数在调用者的作用域。

由于 slice 变量包含一个“slice 描述符”,它仅引用一个底层数组,在您的 Test 函数中,您可以修改 slice 中保存的 slice 描述符 变量连续多次,但这不会影响调用者及其 a 变量。

Test 函数中,第一个 append 重新分配 slice 变量下的后备数组,复制其原始内容,将 100 附加到它,这就是您所观察到的。从 Test 退出时,slice 变量超出范围, slice 引用的(新)底层数组也是如此。(Jeff Lee 是正确的这不是真正发生的事情,所以更新版本如下;正如他正确指出的那样,this answer 是正确的,虽然可能有点过于简洁。)

Test 函数之外,分配了一个长度为 7、容量为 8 的 slice ,并填充了它的 7 个元素。
Test 函数中,第一个 append 看到 slice 的容量仍然比它的长度大一个元素——换句话说,还有空间可以再添加一个元素无需重新分配。因此它会“吃掉”剩余的元素并将 100 放入其中,之后它会调整 slice 描述符副本中的长度以使其等于 slice 的容量。这不会影响调用者范围内的 slice 描述符。

这就是你所观察到的。从 Test 退出时,slice 变量超出范围, slice 引用的(新)底层数组也是如此。

如果你想让 Test 表现得像 append你必须从中返回新 slice ——就像 append 确实——并且要求 Test 的调用者以与使用 append 相同的方式使用它:

func Test(slice []int) []int {
slice = append(slice, 100)

fmt.Println(slice)

return slice
}

a = Test(a)

请阅读 this article在解释 slice 如何在内部工作之后,它基本上向您展示了如何手动实现 append。然后阅读this .

关于Golang 将项目附加到 slice ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20195296/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com