英文:
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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论