2014-12-20 10 views
2

미리 정의 된 구조체에 정보를 매핑하지 않고 중첩 된 JSON 응답을 구문 분석하려고 노력하고 있습니다.성공적인 형식 어설 션 테스트 방법으로 panic/recover를 사용해도 괜찮습니까?

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 문자열에서 정보를 구문 분석의 수용 방법 : 그래서

 
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] 

나는이 정보를 이동하려면 다음을 사용하고 있습니다 : 빈 인터페이스와

는 그것으로 되돌아 온다 , 또는 더 바람직한 방법이 있습니까?

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

어떤 통찰력을 감상 할 수있다 :

는 여기에 내가 현재 사용하고 올바른 정보를 구문 분석하는 위를 사용하는 예입니다! 감사!

답변

7

확인 the specification for type assertions : 특수 형태

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

의 할당 또는 초기화에 사용

유형의 주장은 추가로 지정되지 않은 부울 값을 산출한다. 어설 션이 유지되면 ok 값은 true입니다. 그렇지 않으면 false이고 v 값은 유형 T에 대한 0 값입니다.이 경우 런타임 패닉이 발생하지 않습니다.

오류 처리를 사용하여 유형을 검사하는 것보다 빠르고 해킹이 덜합니다. 또한 작업 할 map[string]interface{} 쉽게 만들기위한 github.com/zazab/zhash 같은 라이브러리를 고려해 볼 수 있습니다

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 
} 

그래서 당신은 다시 쓸 수 있습니다. 또는, 물론, encoding/json 중 하나가 어떻게 그것을 할 수 있는지 알아 내려고 노력하십시오.