type Student struct { Name string Age int}func main() { data := make([]*Student, 0) src := []Student{ Student{Name: "allen", Age: 30}, Student{Name: "tom", Age: 33}, } for _, m := range src { data = append(data, &m) // notice point!!! } for _, s := range data { fmt.Println(*s) }}为什么这段代码在 Go 中可以运行?输出与预期相反,如下所示。{tom 33}{tom 33}代替{allen 30}{tom 33}我发现的一个解释是m是一个固定指针,因此每次append(data,&m)只附加 的地址m,该地址在迭代期间保持不变。然而,根据这个解释,m似乎是 of *Student,所以&m是 of **Student,但是如何将一个 value( &m)**Student追加到一个数组中呢[]*Student?
3 回答
温温酱
TA贡献1752条经验 获得超4个赞
当范围覆盖切片时,每次迭代都会返回两个值。第一个是索引,第二个是该索引处元素的副本。
因此,它具有您正在迭代的数组/切片的值。
在你的情况下,该值是一个Student
结构
慕田峪7331174
TA贡献1828条经验 获得超13个赞
实际上这与 Go 中一切都是按值传递这一事实有关。
m := range src
m始终是相同的引用,并且其值会更新。查看它的一个简单方法是打印地址
for _, m := range src {
// ---
p := &m
fmt.Printf("%p\n", p)
// ---
data = append(data, &m) // notice point!!!
}
慕的地10843
TA贡献1785条经验 获得超8个赞
首先,你可以通过内省来找出真相m
。另外,您可以在循环之前声明它 ( var m ...
) 作为实验。
现在,你写“我发现 m 是一个固定指针”。首先,我不确定你所说的“固定指针”是什么意思,我也不认为你是这样的。固定(或常量)的是 的地址m
。结论是“因此每次都append(data,&m)
只是附加地址m
”,这正是发生的情况。然而,你的假设“m
似乎是*Student
”是有缺陷的,而是m
类型Student
,就这么简单。
- 3 回答
- 0 关注
- 146 浏览
添加回答
举报
0/150
提交
取消