递归地向数组添加项目不起作用

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

Go adding items to array recursively not working

问题

我一直在进行一些 Golang 编程,通常都很有趣。现在我有这段代码,需要将其从 C# 移植到 Go,但它就是无法正常工作。

这个代码的想法是从数据库中填充一个员工树,但是每次调用时内部的切片都没有被填充。

最好在这里写下代码:

  1. func (db *DalBase) TitleAllChildren(tx *gorp.Transaction) (items []Title, err error) {
  2. var dbChildren []entities.Title
  3. _, err = tx.Select(&dbChildren, "select * from title where idparent is null order by name")
  4. if err != nil {
  5. return
  6. }
  7. items = make([]Title, 0)
  8. for i := range dbChildren {
  9. currItem := &dbChildren[i]
  10. item := &Title{Id: currItem.Id, Name: currItem.Name}
  11. err = db.TitleChildrenRecursive(tx, item)
  12. if err != nil {
  13. return
  14. }
  15. items = append(items, *item)
  16. }
  17. return
  18. }
  19. func (db *DalBase) TitleChildrenRecursive(tx *gorp.Transaction, u *Title) (err error) {
  20. var dbChildren []entities.Title
  21. _, err = tx.Select(&dbChildren, "select * from title where idparent = $1 order by name", u.Id)
  22. if err != nil {
  23. return
  24. }
  25. if len(dbChildren) != 0 {
  26. u.Items = make([]Title, 0)
  27. for i := range dbChildren {
  28. currItem := &dbChildren[i]
  29. item := &Title{Id: currItem.Id, Name: currItem.Name}
  30. err = db.TitleChildrenRecursive(tx, item)
  31. if err != nil {
  32. return
  33. }
  34. u.Items = append(item.Items, *item)
  35. }
  36. }
  37. return
  38. }

我已经在每次递归调用时记录了值,并且它们在函数内部被填充,但是当它向上冒泡到父级时,切片为空。

我不想使用切片的指针,有可能实现吗?

编辑:这是我尝试填充的结构体:

  1. type Title struct {
  2. Id string `json:"id"`
  3. Name string `json:"name"`
  4. Items []Title `json:"items"`
  5. }
英文:

I have been doing some golang programming and usually has been lot of fun. Now I have this code I need to port from C# to go and it is just not working.
The idea is to fill a tree of employees from database but inner slices are not being filled up on each call.
Better to write the code here

  1. func (db *DalBase) TitleAllChildren(tx *gorp.Transaction) (items []Title, err error) {
  2. var dbChildren []entities.Title
  3. _, err = tx.Select(&dbChildren, "select * from title where idparent is null order by name")
  4. if err != nil {
  5. return
  6. }
  7. items = make([]Title, 0)
  8. for i := range dbChildren {
  9. currItem := &dbChildren[i]
  10. item := &Title{Id: currItem.Id, Name: currItem.Name}
  11. err = db.TitleChildrenRecursive(tx, item)
  12. if err != nil {
  13. return
  14. }
  15. items = append(items, *item)
  16. }
  17. return
  18. }
  19. func (db *DalBase) TitleChildrenRecursive(tx *gorp.Transaction, u *Title) (err error) {
  20. var dbChildren []entities.Title
  21. _, err = tx.Select(&dbChildren, "select * from title where idparent = $1 order by name", u.Id)
  22. if err != nil {
  23. return
  24. }
  25. if len(dbChildren) != 0 {
  26. u.Items = make([]Title, 0)
  27. for i := range dbChildren {
  28. currItem := &dbChildren[i]
  29. item := &Title{Id: currItem.Id, Name: currItem.Name}
  30. err = db.TitleChildrenRecursive(tx, item)
  31. if err != nil {
  32. return
  33. }
  34. u.Items = append(item.Items, *item)
  35. }
  36. }
  37. return
  38. }

I have logged the values on each recursive call and they are being filled inside the function, but when it bubbles up to the parent, slices are empty.

I wouldn't like to use pointers to slices, is it possible to implement?

Edit: here is the struct I am trying to fill

  1. type Title struct {
  2. Id string `json:"id"`
  3. Name string `json:"name"`
  4. Items []Title `json:"items"`
  5. }

答案1

得分: 3

你不需要一个指向切片的指针,只要你传递一个指向包含切片的结构体的指针。

每次调用TitleChildrenRecursive时,在追加任何内容之前,你都会用一个新的切片替换原来的切片:

  1. u.Items = make([]Title, 0)

没有必要使用make创建一个新的切片,因为append函数可以正确地处理空切片。

你还应该将[]Title改为[]*Title,这样,如果在将子项添加到切片后进行任何append操作,整个树都会反映出来。

英文:

You won't need a pointer to a slice, as long you are passing around a pointer to the struct which contains your slice.

Each time you call TitleChildrenRecursive, you're replacing your slice with a new one before anything is appended:

  1. u.Items = make([]Title, 0)

There's no need to make a new slice, since append works correctly with a nil slice.

You should also change []Title to []*Title, so that if any append operations happen to children items after they are added to the slice, it's reflected throughout the tree.

huangapple
  • 本文由 发表于 2015年3月6日 22:33:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/28900984.html
匿名

发表评论

匿名网友

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

确定