Golang结构体从输入中获取到不同的值。

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

Golang struct gets different value from input

问题

我在以下代码中看到了奇怪的行为:

type A struct {
    D []int8
}

func main() {
    a := A{D: make([]int8, 0)}
    a.D = append(a.D, 0)

    b := a
    c := a
    b.D = append(b.D, 1)
    c.D = append(c.D, 2)
    fmt.Println(a.D, b.D, c.D)
}

我期望的输出是

[0] [0 1] [0 2]

然而我得到的是

[0] [0 2] [0 2]

有人知道为什么吗...?

附注:如果我注释掉"a.D = append(a.D, 0)"这一行,或者将D的类型从"[ ]int8"更改为"[ ]int",我得到了我期望的结果。很奇怪...

英文:

I am seeing weird behavior in the following code:

type A struct {
    D []int8
}

func main() {
    a := A{D: make([]int8, 0)}
    a.D = append(a.D, 0)

    b := a
    c := a
    b.D = append(b.D, 1)
    c.D = append(c.D, 2)
    fmt.Println(a.D, b.D, c.D)
}

I'm expecting output to be

[0] [0 1] [0 2]

However I got

[0] [0 2] [0 2]

Anyone know why...?

p.s. If I comment out line "a.D = append(a.D, 0)", or change the type of D from "[ ]int8" to "[ ]int", I got what I expected. Weird...

答案1

得分: 4

首先,更改类型并不能解决这个问题:https://play.golang.org/p/fHX3JAtfNz

这里发生的事情与append和引用类型的机制有关。

基本上,这三个结构体都指向同一个底层数组,但每个切片都有自己独特的长度参数。

所以当你向b追加1时,它变成了[0 1],长度为2。c仍然是[0],长度为1。然后你向c追加2,使其变为[0 2],长度为2。无意中,你也改变了b中数组的第二个值。如果你能够在不使用append的情况下改变a的长度,它也将变为[0 2]。

明白了吗?指针和切片很奇怪。完整的解释在这里:https://blog.golang.org/slices

英文:

First off, changing the type doesn't fix it: https://play.golang.org/p/fHX3JAtfNz

What is happening here has to do with the mechanics of append and reference types.

Basically, all three structs are pointing at the same underlying array, but each slice has its own unique length argument.

So when you append 1 to b, it is [0 1] with a length of 2. c is still [0] with a length of 1. You then append 2 to c, making it [0 2] with a length of 2. Inadvertently, you are also changing the second value of the array in b. If you could change the length of the a without append, it would also be [0 2].

Make sense? Pointers and slices are weird. Full story is here: https://blog.golang.org/slices

huangapple
  • 本文由 发表于 2017年5月12日 05:30:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/43925874.html
匿名

发表评论

匿名网友

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

确定