代码之家  ›  专栏  ›  技术社区  ›  Nagri

为什么结构副本中的更改会反映go中的原始结构?

go
  •  0
  • Nagri  · 技术社区  · 4 年前

    我对Go中的传递值感到困惑。我正在做这件事;

    package main
    
    import (
        "fmt"
    )
    
    type point struct {
        x    int
        list []int
    }
    
    func main() {
        p := point{20, []int{1, 2, 3, 4, 5}}
    
        fmt.Printf("Address: %p, Value: %v\n", &p, p)
        passByValue(p, 1)
        fmt.Printf("Address: %p, Value: %v\n", &p, p)
    
    }
    
    func passByValue(copyOfP point, i int) {
        copyOfP.list = append(copyOfP.list[:i], copyOfP.list[i+1:]...)
        fmt.Printf("From passByValue Address: %p, Value: %v\n", &copyOfP, copyOfP)
    }
    

    输出:

    Original p Address: 0xc00000c080, Value: {20 [1 2 3 4 5]}
    passByValue copyOfP Address: 0xc00000c0c0, Value: {20 [1 3 4 5]}
    Original p Address: 0xc00000c080, Value: {20 [1 3 4 5 5]}
    

    不应该 copyOfP 是以下内容的副本 p 不反思原创 p 不管怎样。

    这里发生了什么事?

    0 回复  |  直到 4 年前
        1
  •  1
  •   p1gd0g    4 年前
    func main() {
    
        // history.ReadlineTest()
    
        p := point{20, []int{1, 2, 3, 4, 5}}
    
        fmt.Printf("Address: %p, Value: %v\n", &p.list[0], p)
        passByValue(p, 1)
        fmt.Printf("Address: %p, Value: %v\n", &p.list[0], p)
    }
    
    func passByValue(copyOfP point, i int) {
        copyOfP.list = append(copyOfP.list[:i], copyOfP.list[i+1:]...)
        fmt.Printf("From passByValue Address: %p, Value: %v\n", &copyOfP.list[0], copyOfP)
    }
    
    Address: 0xc00001a0c0, Value: {20 [1 2 3 4 5]}
    From passByValue Address: 0xc00001a0c0, Value: {20 [1 3 4 5]}
    Address: 0xc00001a0c0, Value: {20 [1 3 4 5 5]}
    

    “列表”切片重复使用了相同的内存。