我遇到過這樣一種情況,我有一些可能是無窮大/NaN 的 float64 欄位,并且嘗試編組為 JSON 會導致不支持 Inf 型別的錯誤。
type Something interface {
Id string `firestore:"id"`
NumberA float64 `firestore:"numberA"`
NumberB float64 `firestore:"numberB"`
NumberC float64 `firestore:"numberC"`
}
這個結構最初是通過另一個庫(Google Firestore)填充的。
實際上,這個結構要大得多,有更多的浮點欄位。
我想我可以使用下面這樣的回圈來使用反射來找到它們,但我想知道是否有更清潔的方法或更慣用的方法。
v := reflect.ValueOf(structVar)
typeOfS := v.Type()
for i := 0; i< v.NumField(); i {
if typeOfS.Field(i).Type.Kind() == reflect.Float64 && math.IsInf(v.Field(i).Interface().(float64), 1) {
// ... some logic I'll put here
}
}
我不明白如何實作自定義編組,所以也許這可能是處理 Inf 的一個選項?
uj5u.com熱心網友回復:
值的自定義處理可以通過實作Marshaler介面的自定義型別來完成。Something但是,您的型別格式不正確。它被定義為type Something interface{},而實際上應該是type Something struct:
type Something struct {
Id string `firestore:"id"`
NumberA JSONFloat `firestore:"numberA"`
NumberB JSONFloat `firestore:"numberB"`
NumberC JSONFloat `firestore:"numberC"`
}
type JSONFloat float64
func (j JSONFloat) MarshalJSON() ([]byte, error) {
v := float64(j)
if math.IsInf(j, 0) {
// handle infinity, assign desired value to v
// or say /- indicates infinity
s := " "
if math.IsInf(v, -1) {
s = "-"
}
return []byte(s), nil
}
return json.Marshal(v) // marshal result as standard float64
}
func (j *JSONFloat) UnsmarshalJSON(v []byte) error {
if s := string(v); s == " " || s == "-" {
// if /- indiciates infinity
if s == " " {
*j = JSONFloat(math.Inf(1))
return nil
}
*j = JSONFloat(math.Inf(-1))
return nil
}
// just a regular float value
var fv float64
if err := json.Unmarshal(v, &fv); err != nil {\
return err
}
*j = JSONFloat(fv)
return nil
}
應該這樣做
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/520337.html
標籤:json去编组
上一篇:如何修改gogin的默認埠?我的8080埠正在使用中
下一篇:撰寫文本檔案時控制文本對齊方式
