Ошибка времени выполнения при разборе массива JSON и элементов карты с запятыми

Дейв Чейни, один из ведущих специалистов в предметной области по Go, писал: "При инициализации переменной составным литералом Go требует, чтобы каждая строка составного литерала заканчивалась запятой, даже последняя строка вашего объявления. Это результат правила точки с запятой."

Однако когда я пытаюсь применить это красивое правило к тексту JSON, синтаксический анализатор, похоже, не согласен с этой философией. В приведенном ниже коде удаление запятой работает. Есть ли исправление для этого, чтобы я мог видеть только одно изменение строки, когда я добавляю элементы в мои различия?

package main

import (
    "fmt"
    "encoding/json"
)

type jsonobject struct {
    Objects []ObjectType `json:"objects"`
}

type ObjectType struct {
    Name string `json:"name"`
}

func main() {
    bytes := []byte(`{ "objects": 
        [ 
            {"name": "foo"}, // REMOVE THE COMMA TO MAKE THE CODE WORK!
        ]}`)
    jsontype := &jsonobject{}
    json.Unmarshal(bytes, &jsontype)
    fmt.Printf("Results: %v\n", jsontype.Objects[0].Name) // panic: runtime error: index out of range
}

2 ответа

Решение

Нет. Спецификация JSON не допускает использование запятой.

Это не правильный JSON:

{ "objects": 
    [ 
        {"name": "foo"},
]}

Это синтаксис Go, который необходимо использовать через запятую, если перечисление не закрыто в строке ( подробнее об этом), например:

// Slice literal:
s := []int {
    1,
    2,
}

// Function call:
fmt.Println(
    "Slice:",
    s,
)

Даже если бы вы могли "убедить" один конкретный анализатор JSON молча проглотить его, другие действительные анализаторы JSON по праву сообщат об ошибке. Не делай этого.

Хотя замыкающие запятые не являются допустимыми для JSON, некоторые языки изначально поддерживают замыкающие запятые, особенно JavaScript, поэтому вы можете увидеть их в своих данных.

Лучше удалить запятые в конце, но если вы не можете изменить свои данные, используйте анализатор JSON, который поддерживает запятые в конце, например HuJSON (также известный как Human JSON), который поддерживает запятые в конце и комментарии в JSON. Это мягкая вилка, и последние 3 коммита сделаны известным Xoogler и членом команды Ex-Golang Брэдом Фитцпатриком .

The Unmarshalсинтаксис такой же, как encoding/json, просто используйте:

      err := hujson.Unmarshal(data, v)

Я использовал его, и он работает, как описано.

Другие вопросы по тегам