Строка в формат приема float64 «.01»

# #go

Вопрос:

Если я получу от API строку, соответствующую формату «.01», и у меня будет такая структура:

тип Mystruct структура { Val float64 json:"val,string" }

В этом случае я получаю попытку разархивировать val в float64. Есть ли способ, которым я могу это сделать?

Комментарии:

1. Это должно сработать. Можете ли вы более конкретно рассказать о проблеме, с которой вы сталкиваетесь?

2. @hobbs я получаю сообщение об ошибке invalid use of ,string struct tag, trying to unmarshal ".01" into float64

3. хм, ладно, я понимаю почему. .01 на самом деле это не был бы допустимый числовой литерал json (он должен был бы быть 0.01 ), поэтому ,string он не принимает его, хотя это может ParseFloat быть просто нормально. Продолжайте с одним из других ответов, и спасибо за предоставление этой детали.

Ответ №1:

Добавьте строковое поле для записи строкового значения:

 type Mystruct struct {
    Val  float64 `json:"-"`
    XVal string  `json:"val"`
}
 

Разархивируйте документ JSON. Преобразуйте строковое значение в значение с плавающей точкой:

 var v Mystruct
err := json.Unmarshal([]byte(data), amp;v)
if err != nil {
    log.Fatal(err)
}
v.Val, err = strconv.ParseFloat(v.XVal, 64)
if err != nil {
    log.Fatal(err)
}
 

Ответ №2:

Я рекомендую определить псевдоним типа, который вы можете использовать в любом месте.

 package main

import (
    "encoding/json"
    "fmt"
    "strconv"
    "strings"
)

type MyFloat64 float64

func (f *MyFloat64) UnmarshalJSON(data []byte) error {
    raw := string(data)
    raw = strings.TrimPrefix(raw, """)
    raw = strings.TrimSuffix(raw, """)
    if parsedFloat, err := strconv.ParseFloat(raw, 64); err != nil {
        return err
    } else {
        *f = MyFloat64(parsedFloat)
        return nil
    }
}

type MyObj struct {
    Val1 MyFloat64
    Val2 string
}

func main() {
    j := `{"Val1":"0.01", "Val2":"0.01"}`
    o := MyObj{}
    err := json.Unmarshal([]byte(j), amp;o)
    if err != nil {
        fmt.Println(err)
    } else {
        b, _ := json.Marshal(o)
        fmt.Println("in:", j)
        fmt.Println("out:", string(b))
    }
}
 

выход:

 in: {"Val1":"0.01", "Val2":"0.01"}
out: {"Val1":0.01,"Val2":"0.01"}