Golang 将项目附加到切片

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


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]


MMMHUHU
浏览 235回答 3
3回答

Helenr

在您的示例slice中,Test函数的参数接收调用者作用域中变量的副本a。由于切片变量包含一个仅引用底层数组的“切片描述符”&nbsp;,因此在您的Test函数中,您可以slice连续多次修改保存在变量中的切片描述符,但这不会影响调用者及其a变量。在Test函数外部,分配了一个长度为 7 和容量为 8 的切片,并填充了它的 7 个元素。在Test函数内部,第一个append看到切片的容量仍然比它的长度大一个元素——换句话说,还有一个空间可以添加一个元素而无需重新分配。所以它“吃掉”剩余的元素并将其放置100到它上面,然后它调整切片描述符副本中的长度,使其等于切片的容量。这不会影响调用者范围内的切片描述符。这就是你正在观察的。从 退出时Test,slice变量超出范围,切片引用的(新)底层数组也超出范围。如果你想让Test行为像append,你必须从中返回新的切片——就像 doappend一样——并要求 的调用者以Test与使用相同的方式使用它append:func Test(slice []int) []int {&nbsp; &nbsp; slice = append(slice, 100)&nbsp; &nbsp; fmt.Println(slice)&nbsp; &nbsp; return slice}a = Test(a)

料青山看我应如是

典型append用法是a = append(a, x)因为append可以就地修改其参数或返回其参数的副本以及附加条目,具体取决于其输入的大小和容量。使用先前附加到的切片可能会产生意想不到的结果,例如a := []int{1,2,3}a = append(a, 4)fmt.Println(a)append(a[:3], 5)fmt.Println(a)可以打印[1 2 3 4][1 2 3 5]

慕桂英3389331

为了使您的代码工作而不必从 Test 返回切片,您可以传递这样的指针:package mainimport (&nbsp; &nbsp; "fmt")var a = make([]int, 7, 8)func Test(slice *[]int) {&nbsp; &nbsp; *slice = append(*slice, 100)&nbsp; &nbsp; fmt.Println(*slice)}func main() {&nbsp; &nbsp; for i := 0; i < 7; i++ {&nbsp; &nbsp; &nbsp; &nbsp; a[i] = i&nbsp; &nbsp; }&nbsp; &nbsp; Test(&a)&nbsp; &nbsp; fmt.Println(a)}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go