为什么使用切片扩展(...)时指针的地址会改变?

问题描述 投票:0回答:1
func main() {
    arr := make([]*int, 5)
    for i := 0; i < len(arr); i++ {
        n := i
        arr[i] = &n
    }
    fmt.Println(arr) // [0x1400012a2d0 0x1400012a2d8 0x1400012a2e0 0x1400012a2e8 0x1400012a2f0]

    list := make([]*int, 0)
    list = append(arr[:1], arr[2:]...)
    fmt.Println(list) // [0x1400012a2d0 0x1400012a2e0 0x1400012a2e8 0x1400012a2f0]
    fmt.Println(arr)  // [0x1400012a2d0 0x1400012a2e0 0x1400012a2e8 0x1400012a2f0 0x1400012a2f0]
}

在最后一个 Println() 中,我想要

[0x1400012a2d0 0x1400012a2d8 0x1400012a2e0 0x1400012a2e8 0x1400012a2f0]
,但我已经得到了
[0x1400012a2d0 0x1400012a2e0 0x1400012a2e8 0x1400012a2f0 0x1400012a2f0]

我不明白为什么地址会改变。

是因为切片扩展导致的吗? 那么,为什么会出现这样的情况呢?

请让我知道这个问题。 谢谢。

go
1个回答
0
投票

另请参阅“在 go 中组合两个切片的惯用方法和风格是什么?

让我们稍微简化一下你的程序:

package main

import "fmt"

func main() {
    arr := make([]int, 5)
    for i := 0; i < len(arr); i++ {
        arr[i] = i
    }
    fmt.Println(arr) // [0 1 2 3 4]

    arr1 := arr[:1]
    arr2 := arr[2:]

    fmt.Println(arr1, len(arr1), cap(arr1)) // [0] 1 5
    fmt.Println(arr2, len(arr2), cap(arr2)) // [2 3 4] 3 3

    list := append(arr1, arr2...)
    fmt.Println(list) // [0 2 3 4]
    fmt.Println(arr)  // [0 2 3 4 4]
}

您正在做什么:您正在创建一个大小为 5 的底层数组,其中

arr
是引用它的切片。然后创建两个切片
arr1
arr2
引用相同的底层数组。

当您将

arr2
附加到
arr1
时,
arr1
的底层数组有足够的空间(容量),因此
arr2
的元素只是简单地复制而无需重新分配。

由于您保持原始

list
,引用相同的底层数组,您会看到镜像在那里的效果。

© www.soinside.com 2019 - 2024. All rights reserved.