英文:
Go adding items to array recursively not working
问题
我一直在进行一些 Golang 编程,通常都很有趣。现在我有这段代码,需要将其从 C# 移植到 Go,但它就是无法正常工作。
这个代码的想法是从数据库中填充一个员工树,但是每次调用时内部的切片都没有被填充。
最好在这里写下代码:
func (db *DalBase) TitleAllChildren(tx *gorp.Transaction) (items []Title, err error) {
var dbChildren []entities.Title
_, err = tx.Select(&dbChildren, "select * from title where idparent is null order by name")
if err != nil {
return
}
items = make([]Title, 0)
for i := range dbChildren {
currItem := &dbChildren[i]
item := &Title{Id: currItem.Id, Name: currItem.Name}
err = db.TitleChildrenRecursive(tx, item)
if err != nil {
return
}
items = append(items, *item)
}
return
}
func (db *DalBase) TitleChildrenRecursive(tx *gorp.Transaction, u *Title) (err error) {
var dbChildren []entities.Title
_, err = tx.Select(&dbChildren, "select * from title where idparent = $1 order by name", u.Id)
if err != nil {
return
}
if len(dbChildren) != 0 {
u.Items = make([]Title, 0)
for i := range dbChildren {
currItem := &dbChildren[i]
item := &Title{Id: currItem.Id, Name: currItem.Name}
err = db.TitleChildrenRecursive(tx, item)
if err != nil {
return
}
u.Items = append(item.Items, *item)
}
}
return
}
我已经在每次递归调用时记录了值,并且它们在函数内部被填充,但是当它向上冒泡到父级时,切片为空。
我不想使用切片的指针,有可能实现吗?
编辑:这是我尝试填充的结构体:
type Title struct {
Id string `json:"id"`
Name string `json:"name"`
Items []Title `json:"items"`
}
英文:
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
func (db *DalBase) TitleAllChildren(tx *gorp.Transaction) (items []Title, err error) {
var dbChildren []entities.Title
_, err = tx.Select(&dbChildren, "select * from title where idparent is null order by name")
if err != nil {
return
}
items = make([]Title, 0)
for i := range dbChildren {
currItem := &dbChildren[i]
item := &Title{Id: currItem.Id, Name: currItem.Name}
err = db.TitleChildrenRecursive(tx, item)
if err != nil {
return
}
items = append(items, *item)
}
return
}
func (db *DalBase) TitleChildrenRecursive(tx *gorp.Transaction, u *Title) (err error) {
var dbChildren []entities.Title
_, err = tx.Select(&dbChildren, "select * from title where idparent = $1 order by name", u.Id)
if err != nil {
return
}
if len(dbChildren) != 0 {
u.Items = make([]Title, 0)
for i := range dbChildren {
currItem := &dbChildren[i]
item := &Title{Id: currItem.Id, Name: currItem.Name}
err = db.TitleChildrenRecursive(tx, item)
if err != nil {
return
}
u.Items = append(item.Items, *item)
}
}
return
}
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
type Title struct {
Id string `json:"id"`
Name string `json:"name"`
Items []Title `json:"items"`
}
答案1
得分: 3
你不需要一个指向切片的指针,只要你传递一个指向包含切片的结构体的指针。
每次调用TitleChildrenRecursive
时,在追加任何内容之前,你都会用一个新的切片替换原来的切片:
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:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论