Целые числа JSON, возвращаемые как 0, когда они должны быть значениями - PullRequest
0 голосов
/ 03 ноября 2019

У меня есть следующий файл JSON, и я пытаюсь разобрать его.

{
"coord":
{
"lon":-121.31,
"lat":38.7},
"weather":[
{
"id":800,
"main":"Clear",
"description":"clear sky",
"icon":"01d"}
],
"base":"stations",
"main":
{
"temp":73.26,
"pressure":1018,
"humidity":17,
"temp_min":68,
"temp_max":77},

Ожидаемый результат:Текущая температура: 73Сегодняшний минимум: 68Сегодняшний максимум: 77Текущая влажность: 17%

но вместо этого он возвращает:Текущая температура: 0Сегодняшний минимум: 0Сегодняшний максимум: 0Текущая влажность: 0%

Это код, который я пытаюсь использовать для получения желаемого результата:

package main

import (
    "encoding/json"
    "fmt"
    "io/ioutil"
    "os"
    "strconv"
)


type Daily struct {
    Currenttemp int `json:"temp"`
    Mintemp     int `json:"temp_min"`
    Maxtemp     int `json:"temp_max"`
    Humidity    int `json:"humidity"`
}


func main() {
    jsonFile, err := os.Open("jsontest1.json")
    if err != nil {
        fmt.Println(err)
    }

    fmt.Println("Successfully Opened jsontest1.json")

    defer jsonFile.Close()

    byteValue, _ := ioutil.ReadAll(jsonFile)

    var daily Daily

    json.Unmarshal(byteValue, &daily)


    fmt.Println("Current Temperature:"+strconv.Itoa(daily.Currenttemp))
    fmt.Println("Today's Low:"+strconv.Itoa(daily.Mintemp))
    fmt.Println("Today's High:"+strconv.Itoa(daily.Maxtemp))
    fmt.Println("Current Humidity:"+strconv.Itoa(daily.Humidity)+"%")


}

что мне не хватает?

1 Ответ

3 голосов
/ 03 ноября 2019

Во-первых, ваш пример ввода JSON плохо отформатирован: он заканчивается на },, когда он должен заканчиваться }}. Это приводит к тому, что json.Unmarshal возвращает ошибку:

unexpected EOF

Исправление, которое приводит к гораздо большему количеству проблем, многие из которых люди отметили в комментариях. Например, ваш ввод не имеет такую ​​же структуру, как ваши struct, а числа JSON декодируются до float64, а не int. Одно из значений - значение с ключом "temp" - 73.26, которое не является целым числом.

Мне не нравится тихое игнорирование неизвестных полей, поэтому мне нравится использовать json.Decoder в которых запрещены неизвестные поля. Это помогает убедиться, что вы не испортили структуру данных, используя неправильный тег или тег на неправильном уровне, потому что, когда вы делаете , вы просто получаете все пропущенные поля как ноль. Поэтому я хотел бы добавить «игнорируемый» декодер для явного игнорирования полей:

type ignored [0]byte
func (i *ignored) UnmarshalJSON([]byte) error {
    return nil
}

Затем вы можете объявить поля типа ignored и при этом дать им теги json (хотя по умолчанию соответствует имениполе имеет тенденцию быть достаточным):

type overall struct {
    Coord   ignored
    Weather ignored
    Base    ignored
    Main    Daily
}

Если вы действительно хотите разархивировать непосредственно к целочисленному типу, вам нужно снова проявить фантазию, что я и сделал в своем примере. Хотя, вероятно, разумнее просто демаршировать прямо к float64. Если вы сделаете это - используйте float64 и не добавляете специальный тип только для того, чтобы игнорировать определенные поля - вы можете отказаться от использования json.NewDecoder.

. чтобы сказать, были ли заполнены ваши поля или нет, но я не делал этого в моем примере. Я отключил чтение файла (и отсутствие проверки ошибок при вызове чтения) и использовал вместо этого жестко закодированные входные данные. Последняя версия, в которой работает декодирование, - здесь, на игровой площадке Go .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...