dongzongzhi6953 2014-12-20 06:17
浏览 49
已采纳

可以使用panic / recover作为测试成功类型断言的方法吗?

I've been working on a way of trying to parse through nested JSON responses without mapping the information to a predefined struct.

With a blank interface it comes back as:

map[name:My Folder parentId:1 created:2014-10-09T16:32:07+0000 deleted:false description:Sync Dir id:3 links:[map[rel:self entity:folder 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]] modified:2014-12-18T18:07:01+0000 permalink:https://web.domain.org/w/SpJYGQkv syncable:true type:d userId:1]

So I'm using the following to navigate this information:

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)
} 

Is this an acceptable way of parsing information from JSON strings, or is there a more preferable method?

Here is the example of using the above to parse out the correct information I'm currently using:

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)
}

Any insight would be appreciated! Thanks!

  • 写回答

1条回答 默认 最新

  • doumao1519 2014-12-20 06:37
    关注

    Check the specification for type assertions:

    A type assertion used in an assignment or initialization of the special form

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

    yields an additional untyped boolean value. The value of ok is true if the assertion holds. Otherwise it is false and the value of v is the zero value for type T. No run-time panic occurs in this case.

    This is faster and less hacky than using error handling to check the type.

    So you could rewrite

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

    as

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

    You might also consider a library like github.com/zazab/zhash for making map[string]interface{} easier to work with. Or, of course, try to work out how one of encoding/json's existing modes can do it.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 jupyterthemes 设置完毕后没有效果
  • ¥15 matlab图像高斯低通滤波
  • ¥15 针对曲面部件的制孔路径规划,大家有什么思路吗
  • ¥15 钢筋实图交点识别,机器视觉代码
  • ¥15 如何在Linux系统中,但是在window系统上idea里面可以正常运行?(相关搜索:jar包)
  • ¥50 400g qsfp 光模块iphy方案
  • ¥15 两块ADC0804用proteus仿真时,出现异常
  • ¥15 关于风控系统,如何去选择
  • ¥15 这款软件是什么?需要能满足我的需求
  • ¥15 SpringSecurityOauth2登陆前后request不一致