Вы можете использовать interface{}
для Entry.Value
, и пакет encoding/json
выберет правильный тип во время выполнения: string
для строки JSON и float64
для строки JSON number:
type Entry struct {
Timestamp string `json:"timestamp"`
Value interface{} `json:"value"`
}
for _, s := range []string{
`{ "timestamp": "2020-01-01T00:00:00.000Z", "value": "a string" }`,
`{ "timestamp": "2020-01-01T00:00:00.000Z", "value": 12 }`,
} {
var e Entry
if err := json.Unmarshal([]byte(s), &e); err != nil {
panic(err)
}
fmt.Printf("%#v %T\n", e, e.Value)
}
Это выводит (попробуйте на Go Playground ):
main.Entry{Timestamp:"2020-01-01T00:00:00.000Z", Value:"a string"} string
main.Entry{Timestamp:"2020-01-01T00:00:00.000Z", Value:12} float64
Да, тогда вам понадобится введите утверждение , чтобы вывести набранное значение из Entry.Value
.
Другой вариант - использовать json.Number
, который может содержать как строки, так и числа JSON:
type Entry struct {
Timestamp string `json:"timestamp"`
Value json.Number `json:"value"`
}
Используя это, приведенный выше пример выводит (это на Go Playground ):
main.Entry{Timestamp:"2020-01-01T00:00:00.000Z", Value:"a string"}
main.Entry{Timestamp:"2020-01-01T00:00:00.000Z", Value:"12"}
При использовании json.Number
, вы можете получить доступ к его значению, используя Number.String()
или Number.Int64()
или Number.Float64()
, которые возвращают ошибку, если его значение не является числом.
Здесь следует отметить одну вещь: , если вход JSON является строкой, содержащей действительное число, например, "12"
, тогда Number.Int64()
не сообщит об ошибке, но проанализирует ее и вернет 12
, Это разница по сравнению с использованием intefface{}
(где Entry.Value
останется string
).