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

поэтому я пытаюсь проанализировать ответ JSON. Он может быть многоуровневым. Вот что я сделал:--6-->

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

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

допустим, ответ был следующий:

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

для доступа к ключу foo, увидел площадка делаю так:

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

вот, что такое .() нотации? Правильно ли это?

1 ответов


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

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

ваш пример:

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

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

если вы знаете, отмечая о формате ввода JSON, то да, вы должны использовать общий map[string]interface{} введите, чтобы обработать его. Если вы знаете точную структуру входного JSON, вы можете создать struct чтобы соответствовать ожидаемым полям, и делая это, вы можете unmarshal текст 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)