新人求教:一个关于Go指针的问题

ticsmtc · · 397 次点击 · 开始浏览    置顶
萌新最近刚入门Go语言,遇到一个指针问题很困惑,应该是和语言机制有关系,请教各位前辈一下。 业务代码简化以后可以表达如下: ```go package main import "fmt" func main() { slist := SimpleTest() fmt.Printf("%+#v\n", slist) } type S struct { Data int Children []S } func SimpleTest() (tree []S) { tree = make([]S, 0) points := make([]*S, 0) for index := 0; index <= 5; index++ { tree = append(tree, S{ Data: index, Children: make([]S, 0), }) //标记1 points = append(points, &(tree[index])) } //标记2 //for index := range tree { // points = append(points, &(tree[index])) //} for index := range points { points[index].Children = append(points[index].Children,S{ Data: points[index].Data * 10, Children: make([]S, 0), }) } return } ``` 主要的问题是 单从调试输出的地址来看 标记1和标记2 产生的效果是等价的,但是标记1不能够正常为`S`结构体内部的`Children`赋值 输出的结果为 ```go []main.S{ main.S{Data:0, Children:[]main.S{}}, main.S{Data:1, Children:[]main.S{}}, main.S{Data:2, Children:[]main.S{}}, main.S{Data:3, Children:[]main.S{}}, main.S{Data:4, Children:[]main.S{main.S{Data:40, Children:[]main.S{}}}}, main.S{Data:5, Children:[]main.S{main.S{Data:50, Children:[]main.S{}}}} } ``` 仅有 4,5 中 `Children`赋值正常(为什么?) 如果将`index`值依次变化,使用标记1的情况,输出则为 ```go // index 0 到 0 正常 []main.S{ main.S{Data:0, Children:[]main.S{main.S{Data:0, Children:[]main.S{}}}} } ``` ```go // index 0 到 1 不正常 []main.S{ main.S{Data:0, Children:[]main.S{}}, main.S{Data:1, Children:[]main.S{main.S{Data:10, Children:[]main.S{}}}} } ``` ```go // index 0 到 2 不正常 []main.S{ main.S{Data:0, Children:[]main.S{}}, main.S{Data:1, Children:[]main.S{}}, main.S{Data:2, Children:[]main.S{main.S{Data:20, Children:[]main.S{}}}} } ``` ```go // index 0 到 3 不正常 []main.S{ main.S{Data:0, Children:[]main.S{}}, main.S{Data:1, Children:[]main.S{}}, main.S{Data:2, Children:[]main.S{main.S{Data:20, Children:[]main.S{}}}}, main.S{Data:3, Children:[]main.S{main.S{Data:30, Children:[]main.S{}}}} } ``` `index >= 3` 后仅有最后两个可以正常赋值 而使用标记2 的三行代码进行实现,则正常,输出为 ```go []main.S{ main.S{Data:0, Children:[]main.S{main.S{Data:0, Children:[]main.S{}}}}, main.S{Data:1, Children:[]main.S{main.S{Data:10, Children:[]main.S{}}}}, main.S{Data:2, Children:[]main.S{main.S{Data:20, Children:[]main.S{}}}}, main.S{Data:3, Children:[]main.S{main.S{Data:30, Children:[]main.S{}}}}, main.S{Data:4, Children:[]main.S{main.S{Data:40, Children:[]main.S{}}}}, main.S{Data:5, Children:[]main.S{main.S{Data:50, Children:[]main.S{}}}}} ``` 符合预期情况 问题: 1.为什么使用标记1会出现有的可以赋值正确,有的赋值不正确(检查过`tree` 和 `points` 里的地址了,是一致的), 并且为何会出现最后两个赋值正确 2.标记1和标记2 原理上不同的地方在哪里(按照其他语言的经验,在这个例子中两者应该一样?) Orz... 谢谢各位前辈了! 代码有写的丑陋的地方轻喷

有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:1006366459

397 次点击  ∙  1 赞  
加入收藏 微博
9 回复  |  直到 2020-11-11 14:43:44
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传