Golang 将项目附加到切片 [英] Golang append an item to a slice

查看:24
本文介绍了Golang 将项目附加到切片的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么切片 a 保持不变?append() 是否生成新切片?

Why does the slice a remain the same? Does append() generate a new 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 参数接收一个副本 调用者作用域中的变量 a.

In your example the slice argument of the Test function receives a copy of the variable a in the caller's scope.

由于切片变量包含一个切片描述符"它只是引用一个底层数组,在你的 Test 函数中,你连续多次修改 slice 变量中保存的切片描述符,但是这不会影响调用者及其 a 变量.

Since a slice variable holds a "slice descriptor" which merely references an underlying array, in your Test function you modify the slice descriptor held in the slice variable several times in a row, but this does not affect the caller and its a variable.

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

Inside the Test function, the first append reallocates the backing array under the slice variable, copies its original contents over, appends 100 to it, and that's what you're observing. Upon exiting from Test, the slice variable goes out of scope and so does the (new) underlying array that slice references. (Jeff Lee is correct about that it's not what really happens, so the updated version follows; as he correctly states, this answer is correct, if maybe a bit too terse.)

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

Outside the Test function, a slice of length 7 and capacity 8 is allocated, and its 7 elements filled.
Inside the Test function, the first append sees the that the slice's capacity is still one element larger than its length — in other words, there is room for one more element to add without reallocation. So it "eats up" that remaining element and places 100 to it, after which it adjusts the length in the copy of the slice descriptor to become equal to the slice's capaticy. This does not affect the slice descriptor's in the caller's scope.

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

And that's what you're observing. Upon exiting from Test, the slice variable goes out of scope and so does the (new) underlying array that slice references.

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

If you want to make Test behave like append, you have to return the new slice from it — just like append does — and require the callers of Test to use it in the same way they would use append:

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

    fmt.Println(slice)

    return slice
}

a = Test(a)

请仔细阅读这篇文章,因为它基本上向您展示了如何在解释了切片在内部如何工作之后,手动实现 append.然后阅读this.

Please read this article thoroughly as it basically shows you how to implement append by hand, after explaining how slices are working internally. Then read this.

这篇关于Golang 将项目附加到切片的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆