首页 > 解决方案 > 在 Go 中解组 json

问题描述

我有以下 json 可以使用:

jsonStr := `{"Ok":[true,{"amount_awaiting_confirmation":"0","amount_awaiting_finalization":"0","amount_currently_spendable":"0","amount_immature":"0","amount_locked":"0","last_confirmed_height":"551632","minimum_confirmations":"10","total":"0"}]}`

这是我现在的处理方式:

    resMap := make(map[string]interface{}, 0)
    json.Unmarshal([]byte(jsonStr), &resMap)
    if val, ok := resMap["Ok"]; ok {
        tup := val.([]interface{})
        wMap := tup[1].(map[string]interface{})

        amountAwaitingConfirmation, _ := strconv.ParseInt(wMap["amount_awaiting_confirmation"].(string), 10, 64)
        amountAwaitingFinalization, _ := strconv.ParseInt(wMap["amount_awaiting_finalization"].(string), 10, 64)
        amountCurrentSpendable, _ := strconv.ParseInt(wMap["amount_currently_spendable"].(string), 10, 64)
        amountImmature, _ := strconv.ParseInt(wMap["amount_immature"].(string), 10, 64)
        amountLocked, _ := strconv.ParseInt(wMap["amount_locked"].(string), 10, 64)
        lastConfirmedHeight, _ := strconv.ParseInt(wMap["last_confirmed_height"].(string), 10, 64)
        minimumConfirmations, _ := strconv.ParseInt(wMap["minimum_confirmations"].(string), 10, 64)
        total, _ := strconv.ParseInt(wMap["total"].(string), 10, 64)
    }

有没有一种更简单的方法来处理这个结构,而不必求助于通用 interface{} 转换?

标签: jsongo

解决方案


为了避免所有手动类型断言,您可以做的一件事是使用json.RawMessage. 然后,您至少可以使用结构来解组列表的对象部分。

这是一个使用您发布的 JSON 字符串的示例(这里它在Go Playground中运行):

type OkJson struct {
    Ok []json.RawMessage
}

type Details struct {
    AmountAwaitingConfirmation string `json:"amount_awaiting_confirmation"`
    AmountAwaitingFinalization string `json:"amount_awaiting_finalization"`
    AmountCurrentlySpendable   string `json:"amount_currently_spendable"`
    AmountImmature             string `json:"amount_immature"`
    AmountLocked               string `json:"amount_locked"`
    LastConfirmedHeight        string `json:"last_confirmed_height"`
    MinimumConfirmations       string `json:"minimum_confirmations"`
    Total                      string `json:"total"`
}

func main() {
    var okj OkJson
    _ = json.Unmarshal([]byte(jsonStr), &okj)

    var aBool bool
    _ = json.Unmarshal(okj.Ok[0], &aBool)
    fmt.Println(aBool)

    var details Details
    _ = json.Unmarshal(okj.Ok[1], &details)
    fmt.Println(details)
}

推荐阅读