为什么在GO中切片的内容没有改变?

huangapple go评论81阅读模式
英文:

Why is the content of slice not changed in GO?

问题

我以为在GO语言中,切片是通过引用传递的。但是为什么下面的代码没有改变切片c的内容呢?我是不是漏掉了什么?谢谢。

package main

import (
    "fmt"
)


func call(c []int) {
    c = append(c, 1)
    fmt.Println(c)
}

func main() {
    c := make([]int, 1, 5)
    fmt.Println(c)
    call(c)
    fmt.Println(c)
}

打印的结果是:

[0]
[0 1]
[0]

而我期望的是

[0]
[0 1]
[0 1]

英文:

I thought that in GO language, slices are passed by reference. But why the following code doesn't change the content of slice c? Am I missing something? Thank you.

package main

import (
	"fmt"
)


func call(c []int) {
	c = append(c, 1)
	fmt.Println(c)
}

func main() {
	c := make([]int, 1, 5)
	fmt.Println(c)
	call(c)
	fmt.Println(c)
}

The result printed is:

> [0]
> [0 1]
> [0]

while I was expecting
> [0]
> [0 1]
> [0 1]

答案1

得分: 13

切片的长度保存在切片头部,不通过引用传递。你可以将切片看作一个包含指向数组的指针、长度和容量的结构体。

当你向切片追加元素时,你修改了数据数组中的索引1,然后增加了切片头部的长度。当你返回时,主函数中的c的长度为1,所以打印出相同的数据。

切片以这种方式工作的原因是为了让你可以有多个指向相同数据的切片。例如:

x := []int{1,2,3}
y := x[:2] // [1 2]
z := x[1:] // [2 3]

这三个切片都指向同一个底层数组中重叠的数据。

英文:

The length of the slice is kept in the slice header which is not passed by reference. You can think of a slice as a struct containing a pointer to the array, a length, and a capacity.

When you appended to the slice, you modified index 1 in the data array and then incremented the length in the slice header. When you returned, c in the main function had a length of 1 and so printed the same data.

The reason slices work this way is so you can have multiple slices pointing to the same data. For example:

x := []int{1,2,3}
y := x[:2] // [1 2]
z := x[1:] // [2 3]

All three of those slices point to overlapping data in the same underlying array.

答案2

得分: 1

Go始终按值传递。某些类型是引用类型,例如指针、映射和通道;或者部分引用类型,例如切片(它包含对底层数组的引用以及长度和容量的值)。但无论类型如何,都是按值传递的。因此,对局部变量的赋值永远不会影响外部的任何内容。

英文:

Go is always pass by value. Certain types are reference types, like pointers, maps, channels; or partially reference types, like slices (which consists of a reference to the underlying array and also the values of the length and capacity). But regardless of type everything is passed by value. Thus assigning to a local variable never affects anything outside.

huangapple
  • 本文由 发表于 2012年9月5日 11:37:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/12274167.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定