1 回答
TA贡献1780条经验 获得超5个赞
正确的解决方案是“克隆” float64MarshalJSON并UnmarshalJSON为其定义自定义:
type jsonFloat64 float64
func (f jsonFloat64) MarshalJSON() ([]byte, error) {
return json.Marshal(float64(f))
}
func (f *jsonFloat64) UnmarshalJSON(data []byte) error {
if len(data) >= 2 && data[0] == '"' && data[len(data)-1] == '"' {
data = data[1 : len(data)-1]
}
var tmp float64
err := json.Unmarshal(data, &tmp)
if err != nil {
return err
}
*f = jsonFloat64(tmp)
return nil
}
然后你就可以做这样的事情:
func test(s string) {
err := json.Unmarshal([]byte(s), &struct {
F jsonFloat64
}{})
if err != nil {
fmt.Println(err)
return
}
fmt.Println("success")
}
func main() {
test(`{"f": 1.23}`) // success
test(`{"f": "1.23"}`) // success
}
围棋游乐场
随意调整UnmarshalJSON您的需求,我的对间距非常严格。归功于Dave C,这受到了他对另一个问题的评论的极大启发(该问题还具有上述解决方案的更多变化)。
或者,您可以使用正则表达式预处理 JSON 数据,但如果上述解决方案是可行的选择,则不要这样做,它会快得多。
re := regexp.MustCompile(`(":\s*)([\d\.]+)(\s*[,}])`)
rawJsonByteArray = re.ReplaceAll(rawJsonByteArray, []byte(`$1"$2"$3`))
- 1 回答
- 0 关注
- 303 浏览
添加回答
举报