gconv reflect.Value.Convert: value of type float64 cannot be converted to type decimal.Decimal
这是GoFrame 框架的gconv模块的问题不是mapstruct。错误信息reflect.Value.Convert: value of type float64 cannot be converted to type decimal.Decimal表明gconv无法自动将float64转换为decimal.Decimal类型。让我搜索相关解决方案搜索网页gconv float64 convert decimal.Decimal GoFrame gconv decimal.Decimal 转换失败 gconv 自定义类型转换 GoFrame decimal.Decimal 映射47 个结果明白了这是GoFrame 框架gconv模块的问题。错误表明gconv无法自动将float64转换为decimal.Decimal类型。根据搜索结果这是已知问题GoFrame v2.4 已修复gvar.Var到decimal.Decimal的转换但float64到decimal.Decimal仍需自定义转换器。以下是完整的解决方案 解决方案方案 1注册自定义类型转换器推荐使用gconv.RegisterConverter或RegisterTypeConverterFunc注册float64到decimal.Decimal的转换go复制package main import ( github.com/gogf/gf/v2/util/gconv github.com/shopspring/decimal ) // 在程序启动时注册init 或 main 中 func init() { // 方式 1使用 RegisterConverter全局注册 err : gconv.RegisterConverter(func(f float64) (*decimal.Decimal, error) { d : decimal.NewFromFloat(f) return d, nil }) if err ! nil { panic(err) } // 方式 2如果有 string 类型也需要转换 err gconv.RegisterConverter(func(s string) (*decimal.Decimal, error) { d, err : decimal.NewFromString(s) if err ! nil { return nil, err } return d, nil }) if err ! nil { panic(err) } } // 使用示例 func main() { type Source struct { Amount float64 json:amount } type Target struct { Amount decimal.Decimal json:amount } src : Source{Amount: 123.45} var tgt Target // 现在可以成功转换 err : gconv.Scan(src, tgt) if err ! nil { panic(err) } fmt.Printf(转换成功: %v\n, tgt.Amount) // 123.45 }RegisterConverter必须在程序启动时注册且T2必须是指针类型方案 2使用Converter实例GoFrame v2.9 推荐如果你需要更严格的错误处理使用gconv.NewConverter()创建独立转换器go复制package main import ( fmt github.com/gogf/gf/v2/util/gconv github.com/shopspring/decimal ) func main() { // 创建独立转换器 converter : gconv.NewConverter() // 注册 float64 - decimal.Decimal 转换 err : converter.RegisterTypeConverterFunc(func(f float64) (*decimal.Decimal, error) { d : decimal.NewFromFloat(f) return d, nil }) if err ! nil { panic(err) } type Source struct { Price float64 json:price } type Target struct { Price decimal.Decimal json:price } src : Source{Price: 99.99} var tgt Target // 使用 Scan 转换 err converter.Scan(src, tgt) if err ! nil { fmt.Println(转换失败:, err) return } fmt.Printf(价格: %s\n, tgt.Price.String()) // 99.99 }Converter接口提供严谨的错误处理转换失败会返回错误而非零值方案 3为结构体实现UnmarshalValue接口如果你控制目标结构体可以实现自定义反序列化go复制package main import ( fmt github.com/gogf/gf/v2/util/gconv github.com/shopspring/decimal ) type Money struct { decimal.Decimal } // UnmarshalValue 实现 gconv 自定义转换 func (m *Money) UnmarshalValue(value interface{}) error { switch v : value.(type) { case float64: m.Decimal decimal.NewFromFloat(v) case string: d, err : decimal.NewFromString(v) if err ! nil { return err } m.Decimal d case decimal.Decimal: m.Decimal v default: return fmt.Errorf(unsupported type: %T, value) } return nil } type Source struct { Amount float64 json:amount } type Target struct { Amount Money json:amount } func main() { src : Source{Amount: 888.88} var tgt Target err : gconv.Scan(src, tgt) if err ! nil { panic(err) } fmt.Printf(金额: %s\n, tgt.Amount.String()) // 888.88 }UnmarshalValue方法会在 gconv 转换时自动调用适合需要精细控制的场景方案 4升级 GoFrame 版本如果你使用的是GoFrame v2.4 以下版本建议升级bash复制go get github.com/gogf/gf/v2latestv2.4 已修复的问题gvar.Var转decimal.Decimal失败time.Time非标格式字符串解析失败但float64到decimal.Decimal仍需自定义转换器。⚡ 快速修复代码如果你现在急需修复复制这段代码到项目初始化处go复制package utils import ( github.com/gogf/gf/v2/util/gconv github.com/shopspring/decimal ) // InitGconvConverters 注册所有自定义转换器 func InitGconvConverters() error { // float64 - decimal.Decimal if err : gconv.RegisterConverter(func(f float64) (*decimal.Decimal, error) { d : decimal.NewFromFloat(f) return d, nil }); err ! nil { return err } // string - decimal.Decimal if err : gconv.RegisterConverter(func(s string) (*decimal.Decimal, error) { d, err : decimal.NewFromString(s) if err ! nil { return nil, err } return d, nil }); err ! nil { return err } // int64 - decimal.Decimal if err : gconv.RegisterConverter(func(i int64) (*decimal.Decimal, error) { d : decimal.NewFromInt(i) return d, nil }); err ! nil { return err } return nil }然后在main.go中调用go复制func main() { if err : utils.InitGconvConverters(); err ! nil { panic(err) } // ... 后续代码 }❓ 请确认为了给你最精确的解决方案请告诉我你的 GoFrame 版本go list -m github.com/gogf/gf/v2完整的错误堆栈确认是gconv.Scan还是gconv.Struct触发源数据类型是什么float64、string、还是map[string]interface{}目标结构体字段类型decimal.Decimal还是*decimal.Decimal提供这些信息后我可以给出针对性的修复代码。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2446720.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!