Доступ к вложенной карте типа map[string]interface{} в Golang



Итак, я пытаюсь разобрать ответ JSON. Он может быть на несколько уровней глубже. Вот что я сделал:



var result map[string]interface{}
json.Unmarshal(apiResponse, &result)


Во-первых, правильно ли это делать?



Предположим, что ответ был следующим:



{
"args": {
"foo": "bar"
}
}


Чтобы получить доступ к ключу foo, я увидел игровую площадку , делающую это:



result["args"].(map[string]interface{})["foo"]


Здесь, что такое .() обозначение? Это правильно?

1139   1  

1 ответ:

Обозначение x.(T) называется утверждением типа .

Для выражения x типа интерфейса и типа T первичное выражение x.(T) утверждает, что x не является nil и что значение, хранящееся в x, имеет тип T.

Ваш пример:

result["args"].(map[string]interface{})["foo"]
Это означает, что значение вашей карты results, связанной с ключом "args", имеет тип map[string]interface{} (другая карта с ключами string и любыми значениями). И вы хотите получить доступ к элементу этого карта, связанная с ключом "foo".

Если вы знаете что-то о входном формате JSON, то да, вы должны использовать универсальный тип map[string]interface{} для его обработки. Если вы знаете точную структуру входного JSON, вы можете создать struct, чтобы соответствовать ожидаемым полям, и при этом вы можете разобрать текст JSON в значение вашего пользовательского типа struct, например:

type Point struct {
    Name string
    X, Y int
}

func main() {
    in := `{"Name":"center","X":2,"Y":3}`

    pt := Point{}
    json.Unmarshal([]byte(in), &pt)

    fmt.Printf("Result: %+v", pt)
}

Вывод:

Result: {Name:center X:2 Y:3}

Попробуйте это наGo Playground .

Моделирование входные данные

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

type Data struct {
    Args struct {
        Foo string
    }
}

И доступ к Foo (попробуйте это на Go Playground):

d := Data{}
json.Unmarshal([]byte(in), &d)
fmt.Println("Foo:", d.Args.Foo)

Comments

    Ничего не найдено.