亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Go 在轉換為 JSON 之前如何處理 float infinity

Go 在轉換為 JSON 之前如何處理 float infinity

Go
一只斗牛犬 2023-03-07 13:27:16
我遇到過這樣一種情況,我有一些可能是無窮大/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 的一個選項?
查看完整描述

2 回答

?
慕田峪4524236

TA貢獻1875條經驗 獲得超5個贊

值的自定義處理可以通過實現接口的自定義類型來完成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

}

應該這樣做


查看完整回答
反對 回復 2023-03-07
?
烙印99

TA貢獻1829條經驗 獲得超13個贊

我創建了xhhuango/json來支持 NaN、+Inf 和 -Inf。

type T struct {

    N  float64

    IP float64

    IN float64

}


func TestMarshalNaNAndInf(t *testing.T) {

    s := T{

        N:  math.NaN(),

        IP: math.Inf(1),

        IN: math.Inf(-1),

    }

    got, err := Marshal(s)

    if err != nil {

        t.Errorf("Marshal() error: %v", err)

    }

    want := `{"N":NaN,"IP":+Inf,"IN":-Inf}`

    if string(got) != want {

        t.Errorf("Marshal() = %s, want %s", got, want)

    }

}


func TestUnmarshalNaNAndInf(t *testing.T) {

    data := []byte(`{"N":NaN,"IP":+Inf,"IN":-Inf}`)

    var s T

    err := Unmarshal(data, &s)

    if err != nil {

        t.Fatalf("Unmarshal: %v", err)

    }

    if !math.IsNaN(s.N) || !math.IsInf(s.IP, 1) || !math.IsInf(s.IN, -1)     {

        t.Fatalf("after Unmarshal, s.N=%f, s.IP=%f, s.IN=%f, want NaN, +Inf, -Inf", s.N, s.IP, s.IN)

    }

}


查看完整回答
反對 回復 2023-03-07
  • 2 回答
  • 0 關注
  • 201 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號