去递归添加项目到数组不起作用

去递归添加项目到数组不起作用

问题描述:

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"`
}

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.