对于 `slice` 的参数 `[ ]int`,你感到困惑吗?

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

confused about how parameter of slice ( [ ]int ) work?

问题

我读了这篇文章,其中有一些示例,我无法猜出其中一些的输出...

第一个示例(playground):

package main
import "fmt"
func surprise(a []int) {
    for i := range(a) {
        a[i] = 5
    }
    fmt.Println(a)
}
// Quiz #1
func main() {
    a := []int{1, 2, 3, 4}
    surprise(a)
    fmt.Println(a)
}

输出:

[5 5 5 5]
[5 5 5 5]

而第二个示例(playground):

package main
import "fmt"
func surprise(a []int) {
    a = append(a, 5)
    for i := range(a) {
        a[i] = 5
    }
    fmt.Println(a)
}
// Quiz #2
func main() {
    a := []int{1, 2, 3, 4}
    surprise(a)
    fmt.Println(a)
}

输出:

[5 5 5 5 5]
[1 2 3 4]

所以我认为这是因为在第二个示例中,切片的值被复制到了局部函数中。
但是,我对第四个示例(playground)感到惊讶:

package main
import "fmt"
func surprise(a []int) {
    a = append(a, 5)
    for i := range(a) {
        a[i] = 5
    }
    fmt.Println(a)
}
// Quiz #4
func main() {
    a := []int{1, 2, 3, 4}
    a = append(a, 5)
    surprise(a)
    fmt.Println(a)
}

输出:

[5 5 5 5 5 5]
[5 5 5 5 5]

那么为什么会这样呢?

英文:

I read this article that made some samples, and I failed to guess the output of some of them...

The first one (playground):

package main
import "fmt"
func surprise(a []int) {
    for i := range(a) {
        a[i] = 5
    }
    fmt.Println(a)
}
// Quiz #1
func main() {
    a := []int{1, 2, 3, 4}
    surprise(a)
    fmt.Println(a)
}

output

[5 5 5 5]
[5 5 5 5]

wile the second (playground):

package main
import "fmt"
func surprise(a []int) {
    a = append(a, 5)
    for i := range(a) {
        a[i] = 5
    }
    fmt.Println(a)
}
// Quiz #2
func main() {
    a := []int{1, 2, 3, 4}
    surprise(a)
    fmt.Println(a)
}

output:

[5 5 5 5 5]
[1 2 3 4]

so I think that this is because in the second sample slice value is copied to local function.
but then I was surprised with the fourth sample(playground) :

package main
import "fmt"
func surprise(a []int) {
    a = append(a, 5)
    for i := range(a) {
        a[i] = 5
    }
    fmt.Println(a)
}
// Quiz #4
func main() {
    a := []int{1, 2, 3, 4}
    a = append(a, 5)
    surprise(a)
    fmt.Println(a)
}

opuput:

[5 5 5 5 5 5]
[5 5 5 5 5]

So why is that?

答案1

得分: 1

切片是对数组的一种视图。当你向一个容量不足的切片追加新值时,会分配一个具有更大容量的新数组,并将旧数组的内容复制到新数组中。

所以在第二种情况下,切片是在函数中追加的,所以在那一点上会分配一个新的数组,并且函数将新数组的所有值设置为5。主函数中的切片保持不变。

在第三种情况下,切片是在主函数中追加的,这会创建一个原始大小两倍的新数组。当函数向该数组追加新值时,无需调整大小,因此主函数和函数都在同一个基础数组上操作,唯一的区别是函数中的切片比主函数中的切片多一个元素。它们共享同一个基础数组。

英文:

A slice is a view over an array. When you append new values to a slice that does not have enough capacity, a new array is allocated with larger capacity and the contents of the old array are copied to the new array.

So in the second case, the slice is appended in the function, so at that point a new array is allocated, and the function sets all the values of the new array to 5. The slice in main remains unchanged.

In the third case the slice is appended in main, which creates a new array twice the size of the original. When the function appends a new value to that array, there is no need to resize it, so both main and the function work on the same underlying array, with the difference that the slice in the function is one larger than the one in main. They both share the same underlying array though.

huangapple
  • 本文由 发表于 2022年3月7日 04:06:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/71373831.html
匿名

发表评论

匿名网友

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

确定