JSON 解析におけるデータ型の保持
Golang で JSON データを解析するときに遭遇する課題の 1 つは、数値を浮動小数点数に自動的に変換することです。これにより、特に整数値を扱う場合に、元のデータとの不一致が生じる可能性があります。
この問題に対処するには、JSON 解析中にデータ型を保持するためのいくつかの手法があります。
カスタムJSON 値
1 つのアプローチは、Go が提供するカスタム JSON 値メカニズムを利用することです。これには、json.Marshaler インターフェイスと json.Unmarshaler インターフェイスを実装するカスタム タイプの作成が含まれます。 MarshalJSON メソッドと UnmarshalJSON メソッドをオーバーライドすることで、シリアル化および逆シリアル化中に数値を処理する方法を制御できます。
Go json.Number
もう 1 つのオプションは、json を使用することです。 .Go 1.8 で導入された Number 型。デフォルトでは、JSON の数値は float64 として解析されます。ただし、json.Number を使用し、Int64 メソッドまたは Float64 メソッドを呼び出すことにより、数値をそれぞれ整数または浮動小数点値に明示的に変換できます。
例実装
package main import ( "encoding/json" "fmt" "strconv" "strings" ) type MyJSONNumber struct { json.Number } func (mn *MyJSONNumber) MarshalJSON() ([]byte, error) { if n, err := strconv.Atoi(string(mn.Number)); err == nil { return []byte(strconv.Itoa(n)), nil } return []byte(mn.Number), nil } func (mn *MyJSONNumber) UnmarshalJSON(b []byte) error { if n, err := strconv.Atoi(string(b)); err == nil { mn.Number = strconv.Itoa(n) return nil } mn.Number = string(b) return nil } func main() { str := `{"a":123,"b":12.3,"c":"123","d":"12.3","e":true}` var raw map[string]json.RawMessage err := json.Unmarshal([]byte(str), &raw) if err != nil { panic(err) } parsed := make(map[string]interface{}, len(raw)) for key, val := range raw { s := string(val) jnum := MyJSONNumber{json.Number(s)} n, err := jnum.Int64() if err == nil { parsed[key] = n continue } f, err := jnum.Float64() if err == nil { parsed[key] = f continue } var v interface{} err = json.Unmarshal(val, &v) if err == nil { parsed[key] = v continue } parsed[key] = val } for key, val := range parsed { fmt.Printf("%T: %v %v\n", val, key, val) } }
出力:
int64: a 123 float64: b 12.3 string: c 123 string: d 12.3 bool: e true
以上がGo で JSON を解析するときにデータ型を保持するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。