将结构体分配给结构体内的结构体切片。

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

Assign struct to struct inside slice of struct

问题

在循环中将结构体赋值给另一个结构体时出现了奇怪的行为。

package main

import (
	"fmt"
)

func main() {
	type A struct {
		a string
	}
	type B struct {
		A
		b string
	}
	var z []B
	
	c := A{a:"Test"}
	d := B{A:c, b:"Test"}
	
	fmt.Println(c)
	fmt.Println(d)
	
	z = append(z, B{b:"Test"})
	z = append(z, B{b:"Test"})
	
	fmt.Println(z)
	
	for _, x := range z {
		x.A = c
	}
	
	fmt.Println(z)
}

输出结果:

{Test}
{{Test} Test}
[{{} Test} {{} Test}]
[{{} Test} {{} Test}]

期望的结果:

{Test}
{{Test} Test}
[{{} Test} {{} Test}]
[{{Test} Test} {{Test} Test}]

Go Playground上检查。

英文:

Weird behavior when assign struct to struct inside loop.

package main

import (
	"fmt"
)

func main() {
	type A struct {
		a string
	}
	type B struct {
		A
		b string
	}
	var z []B
	
	c := A{a:"Test"}
	d := B{A:c,b:"Test"}
	
	fmt.Println(c)
	fmt.Println(d)
	
	z = append(z, B{b:"Test"})
	z = append(z, B{b:"Test"})
	
	fmt.Println(z)
	
	for _, x := range z {
		x.A = c
	}
	
	fmt.Println(z)
}

Output:

{Test}
{{Test} Test}
[{{} Test} {{} Test}]
[{{} Test} {{} Test}]

Expected Value:

{Test}
{{Test} Test}
[{{} Test} {{} Test}]
[{{Test} Test} {{Test} Test}]

Check on this Go Playground

答案1

得分: 1

原因是,通过对z进行迭代,你正在复制z的元素,并将其标识为x。换句话说,更新x并不意味着你正在更新z,而是在更新其元素的副本。你应该按照以下方式进行操作:

for i, _ := range z {
    z[i].A = c
}

我已经将相同的代码复制到playground中。

英文:

The reason is, by iterating on z, you are making a copy of elements of z, identified as x. In other words, updating x doesn't mean you're updating z but a copy of it's elements. You should do it as follows:

for i, _ := range z {
    z[i].A = c
}

I've copied the same to playground.

huangapple
  • 本文由 发表于 2021年10月15日 16:17:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/69581769.html
匿名

发表评论

匿名网友

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

确定