前段时间写了个递归树,中间遇到了个坑,按逻辑看是没问题,没想到结果不对。
for _, v := range tree
我在遍历这个tree数组的时候传递的是数组对象,修改了数组的内容但返回时发现没有变化。这就是golang和java的差别,遍历的时候如果是非指针对象,那么golang会copy一个副本v,你修改的只是v的值,除非你修改完再重新放入数组,否则结果是不会变的。或者使用指针传递,使用数组的指针就没问题了。
这应该是golang和java思想的不同之处,golang处处都应该尽量使用指针,特别是大对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 func genGeoTree(arr *[]entity.GeoCommon) []*entity.GeoTree { root := buildGeoRoot(arr) buildGeoChildren(arr, root) return root } func buildGeoRoot(arr *[]entity.GeoCommon) []*entity.GeoTree { var pNodes []*entity.GeoTree for _, v := range *arr { if v.PCode == 0 { var child entity.GeoTree child.Code = v.Code child.Name = v.Name child.Sort = v.Sort child.PCode = v.PCode pNodes = append(pNodes, &child) } } return pNodes } func buildGeoChildren(arr *[]entity.GeoCommon, tree []*entity.GeoTree) { for _, v := range tree { pNodes := make([]*entity.GeoTree, 0) for _, vv := range *arr { if vv.PCode == v.Code { var child entity.GeoTree child.Code = vv.Code child.Name = vv.Name child.Sort = vv.Sort child.PCode = vv.PCode pNodes = append(pNodes, &child) buildGeoChildren(arr, pNodes) } } v.Children = pNodes } }