diff --git a/CHANGELOG.md b/CHANGELOG.md index 18eee13..5bdb989 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # CHANGELOG +## [v1.2.8] - 2026-05-05 +### Fixed +- **JSON 解码器深度增强**: 修复了 `cast.UnmarshalJSON` 在反序列化到 `interface{}` 类型字段时会跳过对象和数组的重大缺陷。 +- **高精度整数解析**: 优化了 JSON 解码过程中的数字处理逻辑。当目标为 `interface{}` 时,优先将整数解析为 `int64` 而非 `float64`,彻底解决了纳秒级时间戳(Nanosecond Timestamp)和 64 位长 ID 的精度丢失问题。 +- **接口兼容性**: 完善了对 `interface{}` 类型的自动类型识别,支持正确解析为 `map[string]any` 和 `[]any`。 + ## [v1.2.6] - 2026-05-04 ### Fixed - **Map 深度合并修复**: 修复了在 `Convert` 或 `ToMap` 过程中,如果目标 Map 已存在该 Key,其原有结构体/Map 值会被直接覆盖而非深度合并的问题。通过引入 `dst.MapIndex` 预读取与临时寻址变量,现已完美支持 Map 下非指针结构体的局部字段覆盖。 diff --git a/json_decoder.go b/json_decoder.go index 059714e..b2f0d29 100644 --- a/json_decoder.go +++ b/json_decoder.go @@ -103,8 +103,24 @@ func (d *decoder) decodeValue(reflectValue reflect.Value, timeFormat string) err switch char { case '{': + if reflectValue.Kind() == reflect.Interface { + m := make(map[string]any) + if err := d.decodeObject(reflect.ValueOf(&m).Elem()); err != nil { + return err + } + reflectValue.Set(reflect.ValueOf(m)) + return nil + } return d.decodeObject(reflectValue) case '[': + if reflectValue.Kind() == reflect.Interface { + var s []any + if err := d.decodeArray(reflect.ValueOf(&s).Elem()); err != nil { + return err + } + reflectValue.Set(reflect.ValueOf(s)) + return nil + } return d.decodeArray(reflectValue) case '"': str, err := d.parseString() @@ -123,6 +139,8 @@ func (d *decoder) decodeValue(reflectValue reflect.Value, timeFormat string) err reflectValue.SetFloat(Float64(str)) case reflect.Bool: reflectValue.SetBool(Bool(str)) + case reflect.Interface: + reflectValue.Set(reflect.ValueOf(str)) default: // 尝试将字符串解析为具体对象(比如内部又是 JSON) if strings.HasPrefix(str, "{") || strings.HasPrefix(str, "[") { @@ -148,7 +166,20 @@ func (d *decoder) decodeValue(reflectValue reflect.Value, timeFormat string) err case reflect.String: reflectValue.SetString(literal) case reflect.Interface: - reflectValue.Set(reflect.ValueOf(literal)) + // 优先作为数字处理以保留精度 (int64) + if literal == "true" { + reflectValue.Set(reflect.ValueOf(true)) + } else if literal == "false" { + reflectValue.Set(reflect.ValueOf(false)) + } else if literal == "null" { + reflectValue.Set(reflect.Zero(reflectValue.Type())) + } else if strings.Contains(literal, ".") || strings.Contains(literal, "e") || strings.Contains(literal, "E") { + reflectValue.Set(reflect.ValueOf(Float64(literal))) + } else if i, err := strconv.ParseInt(literal, 10, 64); err == nil { + reflectValue.Set(reflect.ValueOf(i)) + } else { + reflectValue.Set(reflect.ValueOf(literal)) + } } } return nil