You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Golang中解析含顶层匿名数组的JSON并优雅提取tokens的方法咨询

Golang中解析含顶层匿名数组的JSON并优雅提取tokens的方法咨询

嗨,我完全懂你现在的困扰——用any反复做类型断言确实又繁琐又不够安全,看起来也不优雅。其实你完全可以用结构体来解析这个JSON,之前没成功大概率是没处理好顶层的匿名数组结构,我来给你一步步梳理怎么优化:

首先,我们根据你的JSON结构定义对应的Go结构体,把JSON里的层级对应起来:

// 单个token的结构体,对应JSON里的tokens数组元素
type Token struct {
    Name        string  `json:"name"`
    Type        string  `json:"type"`
    IsList      bool    `json:"isList"`
    Default     string  `json:"default"`
    Description *string `json:"description"` // 用指针处理null值,区分空字符串和null
}

// 顶层数组的元素结构体,包含tokens字段
type QueryResult struct {
    QueryId     string  `json:"queryId"`
    QueryType   string  `json:"queryType"`
    Description *string `json:"description"`
    Tokens      []Token `json:"tokens"`
}

这里Description用指针类型是因为JSON里它可能是null,指针可以明确区分“null”和空字符串的差异;如果不需要这种区分,换成普通字符串也可以,Unmarshal时会把null转成空字符串。

接下来修改你的getRequest函数,用这些结构体来解析,代码会清爽很多:

func getRequest(authToken string) error {
    reqUrl := fmt.Sprintf("https://host.com?params")
    req, err := http.NewRequest(http.MethodGet, reqUrl, nil)
    if err != nil {
        return err
    }
    req.Header.Set("Authorization", "Bearer "+authToken)
    
    resp, err := http.DefaultClient.Do(req)
    if err != nil {
        return err
    }
    defer resp.Body.Close() // 把defer放在resp成功获取后,避免空指针问题
    
    body, err := io.ReadAll(resp.Body)
    if err != nil {
        return err
    }
    
    // 关键:JSON顶层是数组,所以要Unmarshal到[]QueryResult切片类型
    var results []QueryResult
    if err := json.Unmarshal(body, &results); err != nil {
        return err
    }
    
    // 优雅遍历提取tokens
    for _, result := range results {
        for _, token := range result.Tokens {
            fmt.Printf(" - Name: %s\n", token.Name)
            fmt.Printf(" - Type: %s\n", token.Type)
            fmt.Printf(" - IsList: %t\n", token.IsList)
            fmt.Printf(" - Default: %s\n", token.Default)
            // 处理可能为null的描述字段
            if token.Description != nil {
                fmt.Printf(" - Description: %s\n\n", *token.Description)
            } else {
                fmt.Println(" - Description: null\n")
            }
        }
    }
    return nil
}

这样做的好处很明显:

  • 类型安全:编译阶段就能检查字段类型,避免运行时类型断言出错
  • 代码简洁:不用反复写繁琐的类型断言,直接通过结构体字段访问
  • 可读性强:结构体定义清晰展示了JSON的层级结构,后续维护或扩展其他字段也很方便

如果你真的只关心tokens,甚至可以简化结构体(比如只保留外层的Tokens字段),但上面的方式是最规范、扩展性最好的方案。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.07 08:50:26