What does this print? How do you preserve large integer precision when decoding unknown JSON?
Question 452HardGo 1.22 to 1.25
var m map[string]any
json.Unmarshal([]byte(`{"id": 12345678901234567890, "n": 1}`), &m)
fmt.Printf("%T %v\n", m["n"], m["id"])
_, ok := m["n"].(int)
fmt.Println(ok)
Output:
float64 1.2345678901234567e+19
false
Decoding into any maps JSON numbers to float64, objects to map[string]any, arrays to []any. A type assertion to int fails, and integers above 253 silently lose precision — a classic bug with Twitter/Snowflake IDs.
Fixes: decode into a typed struct with int64/uint64, or use Decoder.UseNumber() so numbers become json.Number (a string) which you convert explicitly:
dec := json.NewDecoder(strings.NewReader(`{"id": 12345678901234567890}`))
dec.UseNumber()
var m map[string]any
if err := dec.Decode(&m); err != nil {
log.Fatal(err)
}
num := m["id"].(json.Number)
u, err := strconv.ParseUint(num.String(), 10, 64)
fmt.Println(u, err) // 12345678901234567890 <nil>
json.Number can also be used as a struct field type to accept numbers whose type you decide later.
More on Standard Library, HTTP & Systems Design in Go
- Q450What does this handler send to the client, and why?
- Q451Explain encoding/json struct tag behavior: omitempty, omitzero, "-", and ",string". What does this print?
- Q453You implemented MarshalJSON but it isn't called. Why? Explain receiver rules and the recursion trap.
- Q454json.Unmarshal vs json.Decoder: when to use each, and how do you safely decode a request body?
- Q455What does this print? (nil vs empty slices and maps in JSON)
- Q456How does database/sql connection pooling work? Which settings matter and what causes connection leaks?