萌新最近刚入门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... 谢谢各位前辈了!
代码有写的丑陋的地方轻喷
有疑问加站长微信联系(非本文作者)