Vasili Syrakis
Vasili Syrakis

Reputation: 9601

Having trouble accessing a key in a map inside an []interface

Example code:

package main

import "fmt"

func main() {
    example_container := []interface{}{
        map[string]string{
            "name": "bob",
            "id": "1",
        },
        map[string]string{
            "name": "jim",
            "id": "2",
        },
    }
    fmt.Printf("%v\n", example_container)
    fmt.Printf("%v\n", example_container[0])
    fmt.Printf("%v\n", example_container[0]["name"])
}

Problematic line:

fmt.Printf("%v\n", example_container[0]["name"])

Error:

invalid operation: example_container[0]["name"] (type interface {} does not support indexing)

Question:

How do I access the keys inside this interface, then?

Do I have to define a more elaborate interface with a method set to accomplish this?

Upvotes: 1

Views: 107

Answers (1)

icza
icza

Reputation: 417612

Since your slice type is []interface{}, indexing this slice will give you elements of type interface{}. Values of type interface{} cannot be indexed.

But since you put values of type map[string]string into it, you may use type assertion to obtain a value of that map type, which you can index properly:

fmt.Printf("%v\n", example_container[0].(map[string]string)["name"])

Output (try it on the Go Playground):

[map[name:bob id:1] map[name:jim id:2]]
map[name:bob id:1]
bob

If you know you will always store values of type map[string]string in your example_container slice, best would be to define it like this:

example_container := []map[string]string{
    map[string]string{
        "name": "bob",
        "id":   "1",
    },
    map[string]string{
        "name": "jim",
        "id":   "2",
    },
}

And then you don't need type assertion to access the name:

fmt.Printf("%v\n", example_container[0]["name"])

Try this one on the Go Playground.

Also note that in the composite literal you use to initialize your example_container slice, you can even omit the map type when listing the elements:

example_container := []map[string]string{
    {
        "name": "bob",
        "id":   "1",
    },
    {
        "name": "jim",
        "id":   "2",
    },
}

Upvotes: 5

Related Questions