Golang递归结构体详解

Golang递归结构体详解

type Footer struct {
ID       		uint      			`json:"id,omitempty"`
Name 		string 			`json:"name,omitempty"`
Title 		string 			`json:"title,omitempty"`
Slug 		string 			`json:"slug,omitempty"`
URL  		string 			`json:"url,omitempty"`
Position            unit                           `json:"position,omitempty"`
ParentID          string 			`json:"parent_id,omitempty"`
Child		[]Footer			`json:"list,omitempty"`
}

我正在开发一个端点来显示Footer中的所有数据。在我的getAllFooter端点中,首先我基于parent_id为0的条件查询行。对于Child字段,我基于第一次查询的ID从同一个表中进行查询。所以我的footer表提供了显示某行是否为父级的数据。我能正常显示所有父级,但子级没有显示出来。

我是Go语言的新手,需要学习很多东西。如果有人能给我解释一下,我将非常感激。

这是我的JSON数据响应:

“data”: [ { “id”: 1, “name”: “Term and Policies”, “position”: “1” }, { “id”: 2, “name”: “Customer Service”, “position”: “2” } ]

它甚至没有显示Child字段的内容。我不明白


更多关于Golang递归结构体详解的实战教程也可以访问 https://www.itying.com/category-94-b0.html

2 回复

你确定结构体的Child字段不为空吗?在转换为JSON之前,请使用调试器或打印结构体。

fmt.Printf("%#v", myFooter)

更多关于Golang递归结构体详解的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在您的代码中,Child 字段没有显示是因为递归结构体的数据填充需要递归处理。您需要遍历父级数据,并为每个父级查询其子级数据。以下是解决方案:

首先,修正结构体中的类型错误(unit 应为 uint):

type Footer struct {
    ID       uint     `json:"id,omitempty"`
    Name     string   `json:"name,omitempty"`
    Title    string   `json:"title,omitempty"`
    Slug     string   `json:"slug,omitempty"`
    URL      string   `json:"url,omitempty"`
    Position uint     `json:"position,omitempty"`
    ParentID string   `json:"parent_id,omitempty"`
    Child    []Footer `json:"list,omitempty"`
}

然后,在数据查询中实现递归填充:

func getAllFooter() ([]Footer, error) {
    var footers []Footer
    
    // 查询所有父级(parent_id = 0)
    rows, err := db.Query("SELECT id, name, title, slug, url, position, parent_id FROM footer WHERE parent_id = ?", "0")
    if err != nil {
        return nil, err
    }
    defer rows.Close()
    
    for rows.Next() {
        var footer Footer
        err := rows.Scan(&footer.ID, &footer.Name, &footer.Title, &footer.Slug, &footer.URL, &footer.Position, &footer.ParentID)
        if err != nil {
            return nil, err
        }
        
        // 递归获取子级
        childFooters, err := getChildFooters(footer.ID)
        if err != nil {
            return nil, err
        }
        footer.Child = childFooters
        
        footers = append(footers, footer)
    }
    
    return footers, nil
}

func getChildFooters(parentID uint) ([]Footer, error) {
    var childFooters []Footer
    
    rows, err := db.Query("SELECT id, name, title, slug, url, position, parent_id FROM footer WHERE parent_id = ?", parentID)
    if err != nil {
        return nil, err
    }
    defer rows.Close()
    
    for rows.Next() {
        var child Footer
        err := rows.Scan(&child.ID, &child.Name, &child.Title, &child.Slug, &child.URL, &child.Position, &child.ParentID)
        if err != nil {
            return nil, err
        }
        
        // 递归获取更深层级的子级
        grandchildren, err := getChildFooters(child.ID)
        if err != nil {
            return nil, err
        }
        child.Child = grandchildren
        
        childFooters = append(childFooters, child)
    }
    
    return childFooters, nil
}

在您的端点处理函数中:

func GetAllFooterHandler(w http.ResponseWriter, r *http.Request) {
    footers, err := getAllFooter()
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
    
    w.Header().Set("Content-Type", "application/json")
    json.NewEncoder(w).Encode(map[string]interface{}{
        "data": footers,
    })
}

这个实现会递归地查询数据库,为每个父级构建完整的子级树结构。现在您的JSON响应将包含嵌套的list字段,显示所有层级的子数据。

回到顶部