Чтение внешнего файла JSON - PullRequest
0 голосов
/ 11 июля 2019

Я пытаюсь прочитать следующий файл JSON:

{
    "a":1,
    "b":2,
    "c":3
}

Я пробовал это, но обнаружил, что мне нужно записать каждое поле файла JSON в struct, но я действительно не хочу, чтобы все мои файлы JSON были в моем коде Go.

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

type Data struct {
    A string `json:"a"`
    B string `json:"b"`
    C string `json:"c"`
}

func main() {
    file, _ := ioutil.ReadFile("/path/to/file.json")
    data := Data{}

    if err := json.Unmarshal(file ,&data); err != nil {
        panic(err)
    }
    for _, letter := range data.Letter {
        fmt.Println(letter)
    }
}

Есть ли способ обойти эту вещь с чем-то вроде json.load(file) в Python?

Ответы [ 3 ]

3 голосов
/ 11 июля 2019

Если вы хотите поддерживать только целочисленные значения, вы можете разархивировать ваши данные в map[string]int. Обратите внимание, что порядок карты не определен, поэтому вывод программы ниже не является детерминированным для ввода.

package main

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

func main() {
    file, _ := ioutil.ReadFile("/path/to/file.json")
    var data map[string]int

    if err := json.Unmarshal(file ,&data); err != nil {
        panic(err)
    }
    for letter := range data {
        fmt.Println(letter)
    }
}
2 голосов
/ 11 июля 2019

Вы можете разархивировать любые данные JSON следующим образом:

var data interface{}
if err := json.Unmarshal(..., &data); err != nil {
    // handle error
}

Хотя, таким образом, вы должны обрабатывать все, что связано с отражением так как вы не знаете, какой тип корень data, и его поля. Хуже того, ваш data может вообще не быть map. Это может быть любой допустимый тип данных JSON, например, массив, строка, целое число и т. Д.

Вот ссылка на игровую площадку: https://play.golang.org/p/DiceOv4sATO

1 голос
/ 11 июля 2019

Невозможно сделать что-либо столь же простое, как в Python, потому что Go строго типизирован, поэтому необходимо передать вашу цель в функцию unmarshal.

То, что вы написали, в противном случае можно было бы немного сократить,что-то вроде этого:

func UnmarshalJSONFile(path string, i interface{}) error {
    f, err := os.Open(path)
    if err != nil {
        return err
    }
    defer f.Close()
    return json.NewDecoder(f).Decode(i)
}

Но затем, чтобы использовать его, вы бы сделали это:

func main() {
    data := Data{}
    if err := UnmarshalJSONFile("/path/to/file.json", &data); err != nil {
        panic(err)
    }
}

Но вы можете видеть, что UnmarshalJSONFile настолько прост, что вряд ли это оправдываетстандартная библиотечная функция.

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