zoyi / bingodb

6 stars 1 forks source link

json.Unmarshal() 기본 타입 지정 #7

Closed junbong closed 7 years ago

junbong commented 7 years ago

아래와 같은 JSON이 있을 때,

{
  "foo": "bar",
  "number": 1234,
  "floating": 3.14159265359
}
type Foop struct {
    Foo     string
    Number      interface{}
    Floating    interface{}
}

f := &Foop{}
json.Unmarshal([]byte(InputJson), &f)

fmt.Println(reflect.TypeOf(f.Foo))  // string
fmt.Println(reflect.TypeOf(f.Number))   // float64
fmt.Println(reflect.TypeOf(f.Floating)) // float64

struct의 필드 타입을 명시적으로 지정하지 않았을 때, 숫자 필드가 무조건 float64로 컨버팅 되는 문제.

junbong commented 7 years ago

json.Unmarshal() 대신 json.Decoder를 사용하면 float64 기본 타입 대신 interface{} 형태로 마샬링을 함.

d := json.NewDecoder(strings.NewReader(InputJson))

// UseNumber causes the Decoder to unmarshal a number into an interface{} as a
// Number instead of as a float64.
d.UseNumber()

var anonymous interface{}
d.Decode(&anonymous)
// decoded to map[string]interface {}{"foo":"bar", "number":"1234", "floating":"3.14159265359"}
fmt.Printf("decoded to %#v\n", anonymous)

result, _ := json.Marshal(anonymous)
// encoded to {"floating":3.14159265359,"foo":"bar","number":1234}
fmt.Printf("encoded to %s\n", result)