在golang中使用未知结构的json对象有更简洁的方法吗?

当我有一个可靠的 rest api 端点返回一些简单的 json 时,我可以使用结构来准确定义预期 json 结果的结构,但是我必须使用某些端点来返回非常大且复杂的 json 结果数据,并且这些结果的结构并不总是已知的。


我一直在使用它来解组:


type JsonObj map[string]interface{}


func (jo JsonObj) GetString(name string) (string, error) {

    if val, exists := jo[name]; exists {

        if v, ok := val.(string); ok {

            return v, nil

        }

        return "", errors.New(name+" is not a string")

    }

    return "", errors.New(name+" property not found")

}


func (jo JsonObj) GetFloat64(name string) (float64, error) {

    if val, exists := jo[name]; exists {

        if v, ok := val.(float64); ok {

            return v, nil

        }

        return 0, errors.New(name+" is not a float64")

    }

    return 0, errors.New(name+" property not found")

}

以同样的方式我有GetInt, GetBool, GetSlice, GetJsonObj,


但是正如您所看到的,除了类型断言参数之外,所有这些函数的内容几乎相同。有没有办法传入类型断言参数以将所有这些函数有效地减少为单个函数?


慕哥6287543
浏览 267回答 1
1回答

九州编程

这是我现在最好的,作为一个非常简单的例子:https : //play.golang.org/p/U9WJ0bIJPp 我无法想象你能够压缩/提取它比这更多:package mainimport (    "fmt"    "errors")type T interface{}type JsonObj map[string]Tfunc (jo JsonObj) Type(name string, defaultVal T, typeName string, typeAsserter func(val T) (T, bool)) (T, error){    if val, exists := jo[name]; exists {        if v, ok := typeAsserter(val); ok {            return v, nil        }        return defaultVal, errors.New(name+" is not of type "+typeName)    }    return defaultVal, errors.New(name+" property not found")}func (jo JsonObj) String(name string) (string, error) {    ret, err := jo.Type(name, "", "string", func(val T)(ret T, ok bool){ret, ok = val.(string);return})    return ret.(string), err}func (jo JsonObj) Float64(name string) (float64, error) {    ret, err := jo.Type(name, 0, "float64", func(val T)(ret T, ok bool){ret, ok = val.(float64);return})    return ret.(float64), err}func (jo JsonObj) Int(name string) (int, error) {    ret, err := jo.Type(name, 0, "int", func(val T)(ret T, ok bool){if ret, ok = val.(float64); ok {ret = int(ret.(float64))};return})    return ret.(int), err}func (jo JsonObj) Bool(name string) (bool, error) {    ret, err := jo.Type(name, false, "bool", func(val T)(ret T, ok bool){ret, ok = val.(bool);return})    return ret.(bool), err}func main() {    jo := JsonObj{        "aString": "foo",        "aFloat64": 3.142,        "anInt": 42.0, //in a json string unmarshalling all numbers are float64 even "int"s        "aBool": true,    }    fmt.Println(jo.String("aString"))    fmt.Println(jo.Float64("aFloat64"))    fmt.Println(jo.Int("anInt"))    fmt.Println(jo.Bool("aBool"))    fmt.Println(jo.String("missingString"))    fmt.Println(jo.Bool("anInt"))}但正如评论中提到的,有一个库提供了一种更强大的处理任意 json 的方法,https://github.com/bitly/go-simplejson
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go