Как перебрать интерфейс [] {} в Golang? - PullRequest
0 голосов
/ 04 июля 2018

Я изо всех сил пытаюсь получить ключи и значения следующего интерфейса, что является результатом маршалинга JSON результата, возвращаемого Execute, как показано в этот пример :

[
    [
        {
            "id": 36,
            "label": "TestThing",
            "properties": {
                "schema__testBoolean": [
                    {
                        "id": 40,
                        "value": true
                    }
                ],
                "schema__testInt": [
                    {
                        "id": 39,
                        "value": 1
                    }
                ],
                "schema__testNumber": [
                    {
                        "id": 38,
                        "value": 1.0879834
                    }
                ],
                "schema__testString": [
                    {
                        "id": 37,
                        "value": "foobar"
                    }
                ],
                "uuid": [
                    {
                        "id": 41,
                        "value": "7f14bf92-341f-408b-be00-5a0a430852ee"
                    }
                ]
            },
            "type": "vertex"
        }
    ]
]

A reflect.TypeOf(result) приводит к: []interface{}.

Я использовал это для цикла по массиву:

s := reflect.ValueOf(result)
for i := 0; i < s.Len(); i++ {
  singleVertex := s.Index(i).Elem() // What to do here?
}

Но я застреваю с ошибками вроде:

refle.Value.Interface: не может вернуть значение, полученное из неэкспортированного поле или метод

Ответы [ 2 ]

0 голосов
/ 04 июля 2018

Для получения базового значения интерфейса используйте утверждение типа. Подробнее о Введите утверждение и как оно работает.

package main

import (
    "fmt"
)

func main() {
     res, err := g.Execute( // Sends a query to Gremlin Server with bindings
           "g.V(x)",
            map[string]string{"x": "1234"},
            map[string]string{},
     )
     if err != nil {
          fmt.Println(err)
          return
     }
     fetchValue(res)
}

func fetchValue(value interface{}) {
    switch value.(type) {
    case string:
        fmt.Printf("%v is an interface \n ", value)
    case bool:
        fmt.Printf("%v is bool \n ", value)
    case float64:
        fmt.Printf("%v is float64 \n ", value)
    case []interface{}:
        fmt.Printf("%v is a slice of interface \n ", value)
        for _, v := range value.([]interface{}) { // use type assertion to loop over []interface{}
            fetchValue(v)
        }
    case map[string]interface{}:
        fmt.Printf("%v is a map \n ", value)
        for _, v := range value.(map[string]interface{}) { // use type assertion to loop over map[string]interface{}
            fetchValue(v)
        }
    default:
        fmt.Printf("%v is unknown \n ", value)
    }
}
0 голосов
/ 04 июля 2018

Если вы знаете, что это ваша структура данных, нет никакой причины использовать отражение вообще. Просто используйте утверждение типа:

for key, value := range result.([]interface{})[0].([]interface{})[0].(map[string]interface{}) {
    // key == id, label, properties, etc
}
...