2

我一直在研究一种尝试解析嵌套 JSON 响应而不将信息映射到预定义结构的方法。

使用空白界面,它返回为:

地图[名称:我的文件夹 parentId:1 创建:2014-10-09T16:32:07+0000 已删除:错误描述:同步目录 ID:3 链接:[地图 [rel:self 实体:文件夹 href:https://web .domain.org/rest/folders/3 id:3] map[href:https://web.domain.org/rest/folders/1 id:1 rel:parent entity:folder] map[entity:user href: https://web.domain.org/rest/users/1 id:1 rel:creator]] 修改时间:2014-12-18T18:07:01+0000 永久链接:https://web.domain.org/w/ SpJYGQkv 可同步:真类型:d userId:1]

因此,我使用以下内容来导航此信息:

func NFind(input interface{}, refs...interface{}) (output interface{}) {
    defer func() {if r := recover(); r != nil { output = nil }}()

    for _, ref := range refs {
        switch cur := ref.(type) {
            case string:
                output = input.(map[string]interface{})[cur]
            case int:
                output = input.([]interface{})[cur]
        } 
    }
    return output
}

func NMap(input interface{}) (output map[string]interface{}) {
    defer func() {if r := recover(); r != nil {}}()
    if input == nil { return nil }
    return input.(map[string]interface{})
}

func NArray(input interface{}) (output []interface{}) {
    defer func() {if r := recover(); r != nil {}}()
    if input == nil { return nil }
    return input.([]interface{})
}

func NString(input interface{}) (output string) {
    defer func() {if r := recover(); r != nil {}}()
    if input == nil { return "" }
    return input.(string)
}

func NFloat64(input interface{}) (output float64) {
    defer func() {if r := recover(); r != nil {}}()
    if input == nil { return 0 }
    return input.(float64)
} 

这是从 JSON 字符串解析信息的可接受方式,还是有更可取的方法?

以下是使用上述内容解析出我当前正在使用的正确信息的示例:

func mapCache(input map[string]interface{}, valType string) {
    fmt.Println(input)
    var (
        name string
        href string
        rel string
        links []interface{}
        myMap map[string]interface{}
    )

    if name = NString(NFind(input, "name")); name == "" { return }
    if links = NArray(NFind(input, "links")); links == nil { return }

    for i := 0; i < len(links); i++ {
        if myMap = NMap(links[i]); myMap == nil { return }
        if rel = NString(myMap["rel"]); rel == "" { return }
        if rel == "self" {
            if href = NString(myMap["href"]); href == "" { return }
        }
    }
    CacheDB.Set(valType, name, href, false)
}

任何见解将不胜感激!谢谢!

4

1 回答 1

7

检查类型断言的规范

在特殊形式的赋值或初始化中使用的类型断言

v, ok = x.(T)
v, ok := x.(T)
var v, ok = x.(T)

产生一个额外的无类型布尔值。如果断言成立,则 ok 的值为真。否则它是假的并且 v 的值是类型 T 的零值。在这种情况下不会发生运行时恐慌。

与使用错误处理来检查类型相比,这更快且更简单。

所以你可以重写

func NMap(input interface{}) map[string]interface{} {
    defer func() {if r := recover(); r != nil {}}()
    if input == nil { return nil }
    return input.(map[string]interface{})
}

作为

func NMap(input interface{}) map[string]interface{} {
    if m, ok := input.(map[string]interface{}); ok {
        return m
    }
    return nil
}

您还可以考虑使用github.com/zazab/zhash 之类的库,以便map[string]interface{}更轻松地使用。或者,当然,尝试找出encoding/json现有模式之一如何做到这一点。

于 2014-12-20T06:37:50.053 回答