fix(cast): 修复 JSON 反序列化到 interface{} 时跳过对象/数组的问题,并优化 int64 精度 (by AI)
This commit is contained in:
parent
e052313014
commit
dd63c8eae8
@ -1,5 +1,11 @@
|
|||||||
# CHANGELOG
|
# 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
|
## [v1.2.6] - 2026-05-04
|
||||||
### Fixed
|
### Fixed
|
||||||
- **Map 深度合并修复**: 修复了在 `Convert` 或 `ToMap` 过程中,如果目标 Map 已存在该 Key,其原有结构体/Map 值会被直接覆盖而非深度合并的问题。通过引入 `dst.MapIndex` 预读取与临时寻址变量,现已完美支持 Map 下非指针结构体的局部字段覆盖。
|
- **Map 深度合并修复**: 修复了在 `Convert` 或 `ToMap` 过程中,如果目标 Map 已存在该 Key,其原有结构体/Map 值会被直接覆盖而非深度合并的问题。通过引入 `dst.MapIndex` 预读取与临时寻址变量,现已完美支持 Map 下非指针结构体的局部字段覆盖。
|
||||||
|
|||||||
@ -103,8 +103,24 @@ func (d *decoder) decodeValue(reflectValue reflect.Value, timeFormat string) err
|
|||||||
|
|
||||||
switch char {
|
switch char {
|
||||||
case '{':
|
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)
|
return d.decodeObject(reflectValue)
|
||||||
case '[':
|
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)
|
return d.decodeArray(reflectValue)
|
||||||
case '"':
|
case '"':
|
||||||
str, err := d.parseString()
|
str, err := d.parseString()
|
||||||
@ -123,6 +139,8 @@ func (d *decoder) decodeValue(reflectValue reflect.Value, timeFormat string) err
|
|||||||
reflectValue.SetFloat(Float64(str))
|
reflectValue.SetFloat(Float64(str))
|
||||||
case reflect.Bool:
|
case reflect.Bool:
|
||||||
reflectValue.SetBool(Bool(str))
|
reflectValue.SetBool(Bool(str))
|
||||||
|
case reflect.Interface:
|
||||||
|
reflectValue.Set(reflect.ValueOf(str))
|
||||||
default:
|
default:
|
||||||
// 尝试将字符串解析为具体对象(比如内部又是 JSON)
|
// 尝试将字符串解析为具体对象(比如内部又是 JSON)
|
||||||
if strings.HasPrefix(str, "{") || strings.HasPrefix(str, "[") {
|
if strings.HasPrefix(str, "{") || strings.HasPrefix(str, "[") {
|
||||||
@ -148,9 +166,22 @@ func (d *decoder) decodeValue(reflectValue reflect.Value, timeFormat string) err
|
|||||||
case reflect.String:
|
case reflect.String:
|
||||||
reflectValue.SetString(literal)
|
reflectValue.SetString(literal)
|
||||||
case reflect.Interface:
|
case reflect.Interface:
|
||||||
|
// 优先作为数字处理以保留精度 (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))
|
reflectValue.Set(reflect.ValueOf(literal))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user