# #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"}