改变作为参数传递给 Go 中函数的切片

red*_*chl -1 go slice

我编写了一些代码,其中函数f将切片s作为参数并修改它而不返回它。

由于切片可以被视为对底层数组的引用,因此我认为切片实际上会在该函数的范围之外进行修改,但事实并非如此。

下面的代码就是一个例子(https://play.golang.org/p/Y5JUmDtRXrz)。

package main

import (
    "fmt"
)

func pop(s []int) int {
    first, s := s[0], s[1:]
    return first
}

func main() {
    s := []int{0, 1, 2, 3}
    first := pop(s)
    fmt.Println(first, s)
}
Run Code Online (Sandbox Code Playgroud)

pop(s)实际上返回0,这是预期的。但在输出中s仍然有0第一个元素。

0 [0 1 2 3]

Program exited.
Run Code Online (Sandbox Code Playgroud)

为什么?我该如何解决这个问题?

Adr*_*ian 7

这里发生了两件不同的事情,两者都阻止了这种行为如您所期望的那样:

func pop(s []int) int {
    first, s := s[0], s[1:]
Run Code Online (Sandbox Code Playgroud)

第一个问题(也是更简单的)是您s在这里定义一个新的局部变量,它会隐藏您的函数参数s

其次,切片确实指向底层数组,但切片仍然通过副本传递,就像其他所有内容一样。这意味着:

s = s[1:]
Run Code Online (Sandbox Code Playgroud)

修改s 的副本以在基础数组上拥有不同的窗口。这不会改变调用者中的切片。但是,如果您更改底层数组中的值,这反映在调用方中,例如:

s[1] = 42
Run Code Online (Sandbox Code Playgroud)

您可以在整个教程Go 博客上了解更多相关信息。