如何将API返回的".01"格式字符串反序列化到Go结构体float64字段
反序列化失败原因
Go标准库encoding/json对带有,string标签的float64字段反序列化时,要求字符串内的内容必须符合标准JSON数字规范,必须包含整数部分,.01这类省略前导0的数字字符串不符合规范,因此会抛出解析错误。
解决方案
- 方案1:自定义float64类型,实现
UnmarshalJSON接口
该方案侵入性低,兼容原有逻辑,是最推荐的实现方式。
首先定义自定义浮点类型,自行处理字符串解析逻辑:
import "strconv" type CustomFloat64 float64 func (f *CustomFloat64) UnmarshalJSON(data []byte) error { // 去除JSON字符串首尾的双引号 if len(data) >= 2 && data[0] == '"' && data[len(data)-1] == '"' { data = data[1 : len(data)-1] } // strconv.ParseFloat原生支持.01这类省略前导0的格式 val, err := strconv.ParseFloat(string(data), 64) if err != nil { return err } *f = CustomFloat64(val) return nil }
修改原结构体的字段类型即可:
type Mystruct struct { Val CustomFloat64 `json:"val"` }
后续使用时直接将Val强转为float64即可。
- 方案2:分两步反序列化,手动转换类型
如果不想自定义类型,可以先将字段反序列化为字符串,再手动转换为float64:
import "strconv" type Mystruct struct { ValStr string `json:"val"` Val float64 `json:"-"` // 该字段不参与JSON的序列化和反序列化 } // 反序列化逻辑示例 var res Mystruct if err := json.Unmarshal(apiResponse, &res); err != nil { // 处理反序列化错误 } floatVal, err := strconv.ParseFloat(res.ValStr, 64) if err != nil { // 处理数字解析错误 } res.Val = floatVal
- 方案3:使用支持宽松数字解析的第三方JSON库
如果你可以引入第三方依赖,使用json-iterator这类库开启宽松解析规则,不需要修改原有结构体定义:
import "github.com/json-iterator/go" // 初始化支持宽松数字解析的JSON实例 var json = jsoniter.Config{ SupportLooseNumber: true, }.Froze() // 原有结构体不需要修改 type Mystruct struct { Val float64 `json:"val,string"` } // 直接使用自定义的json实例反序列化即可 var res Mystruct err := json.Unmarshal(apiResponse, &res)
内容的提问来源于stack exchange,提问作者rwehresmann
相关产品推荐
相关产品推荐

