2017-12-07 14 views
-1

golang의 JSON.Marshal()을 사용하여지도에서 JSON 문자열을 만들려고합니다. 그러나 int 값은 큰 따옴표로 묶인 문자열로 표시됩니다.문자열과 정수를 모두 포함하는 골란지도

내 코드가 출력된다

{ "age": 
    { 
     "$gt":"22", 
     "$lt":"20" 
    }, 
    "location": 
    { 
     "$eq":"london" 
    }, 
    "name":{ 
     "$eq":"fred" 
    } 
} 

대신 내가 사용하고

{ "age": 
    { 
     "$gt":22, 
     "$lt":20 
    }, 
    "location": 
    { 
     "$eq":"london" 
    }, 
    "name":{ 
     "$eq":"fred" 
    } 
} 

의 :

var output_map = map[string]map[string]string{} 

//Populate map here 

output_json, err := json.Marshal(output_map) 

if err!= nil { 
    fmt.Println("Error encoding JSON") 
} 

fmt.Println(output_json) 

나의 이해는 JSON.Marshal()가 제대로 정수를 인쇄 할 것입니다 그들이 제공되지만 내지도에는 정수가 포함되지 않습니다. 나는지도를 [string] map [string] int {}로 바꿀 수 있었지만 'name'과 'location'의 문자열 값은 포함하지 않았다.

궁극적 인 문제는 int와 string 값을 모두 포함하는지도가 필요하다는 것입니다. 어떤 종류의 map [string] map [string] {}.

어떻게하면됩니까? 미리 감사드립니다.

해리

답변

2

당신이 제대로 입력 구조체로 데이터를 설명 할 수없는 경우를 입력 한 다음 interface{}의 값을 갖는지도 (기본적으로 모든 유형) 사용을 고려 : 예를 들어

output_map := map[string]map[string]interface{}{} 

:

output_map := map[string]map[string]interface{}{ 
    "age": { 
    "$gt": 18, 
    }, 
    "location": { 
    "eq": "London", 
    }, 
} 
bytes, err := json.MarshalIndent(&output_map, "", " ") 
if err != nil { 
    panic(err) 
} 
// { 
// "age": { 
//  "$gt": 18 
// }, 
// "location": { 
//  "eq": "London" 
// } 
// } 

물론 interface{} 유형을 사용하는 것이 최선의 방법은 아닙니다. 그러나 때로는 특정 사물을 성취하는 유일한 방법이기도합니다. 당신이 구조체를 피하기 위해 만약 내가 maerics에 동의

+1

빠른 답변 감사드립니다. 완벽하게 작동합니다! – Harry

1

,

map[string]interface{}은 갈 수있는 방법이 될 것입니다.

귀하의 콘텐츠에서 mongodb-queries를 다루고 있다고 가정합니다.
다음 코드가 도움이 될 수 있습니다.

이동에서 mongodb를 쿼리하려면 mgo-driver mgo.v2을 권장합니다.
사용자 정의 유형 bson.M을 구현합니다. 위와 동일하지만 db 쿼리에도 사용됩니다.

이 외에도 코드가 더 읽기 쉽습니다.

샘플 : map[string]map[string]string{} 그래서, 마샬링 stringjson.Marshal(interface{}) 반환 json string 만 문자열 값을 포함합니다 : 예상대로

package main 

import (
    "fmt" 
    "gopkg.in/mgo.v2/bson" 
    "encoding/json" 
) 

func main() { 

    bsonMap := bson.M{ 
     "age": bson.M{ 
      "$gt": 22, 
      "$lt": 20, 
     }, 
     "location": bson.M{"$eq": "london",}, 
     "name":  bson.M{"$eq": "fred"}, 
    } 

    bytes, err := json.Marshal(bsonMap) 

    if err != nil { 
     panic(err) 
    } 

    fmt.Println(string(bytes)) 
} 
+0

감사합니다. 네, mongodb 쿼리를 사용하고 있습니다. 나는이 수입을 알지 못했지만 매우 유용하게 보입니다. – Harry

0

귀하의 코드가 작동합니다.

map 대신 struct을 사용해야한다고 생각합니다.

type Age struct { 
    Gt int `json:"gt"` 
    Lt int `json:"lt"` 
} 

type Person struct { 
    Age   Age  `json:"age"` 
    Location string `json:"location"` 
    Name  string `json:"name"` 
} 

을 그리고 단지의 standart json.Marshal(interface{}) 방법으로 마샬링 : 그냥이 같은 구조체, 무언가를 만들 수 있습니다. (이 코드에서 json 태그가 필요하지 않습니다,하지만 당신은 직렬화 된 JSON 문자열의 필드의 이름을 변경하려는 경우 당신은 그것을 사용할 수 있습니다) 내가 main()에 다음 코드를 test.go 파일을 생성

을 :

person := Person{ 
    Age{ 
     22, 
     20, 
    }, 
    "London", 
    "Fred", 
} 

serialized, e := json.Marshal(person) 
if e != nil { 
    fmt.Println(e) 
    return 
} 

fmt.Println(string(serialized)) 

과이 반환

{ 
    "age": 
    { 
     "gt":22, 
     "lt":20 
    }, 
    "location":"London", 
    "name":"Fred" 
} 

PSmap[string]map[string]interface{}을 사용하는 것이 좋습니다.이 경우 사용자의 Unmarshaller (map을 다시 채우기 위해)이 있어야합니다. 구조체를 사용하면 다음과 같이 비 정렬화할 수 있습니다.

deserialized := Person{} 
e = json.Unmarshal(serialized, &deserialized) 
if e != nil { 
    fmt.Println("can't deserialize:", e) 
    return 
}