在[]interface中访问map中的一个键时遇到了问题。

huangapple go评论86阅读模式
英文:

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

问题

示例代码:

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"])
}

有问题的行:

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

错误:

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

问题:

我如何访问接口内部的键?

我需要定义一个更复杂的接口并设置方法来实现这个吗?

英文:

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?

答案1

得分: 5

由于您的切片类型是[]interface{},对该切片进行索引将得到interface{}类型的元素。interface{}类型的值无法进行索引。

但是,由于您将map[string]string类型的值放入其中,您可以使用type assertion来获取该映射类型的值,然后可以正确地进行索引:

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

输出结果(在Go Playground上尝试):

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

如果您知道您将始终在example_container切片中存储map[string]string类型的值,最好将其定义如下:

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

然后,您无需进行类型断言即可访问名称:

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

Go Playground上尝试这个示例。

还请注意,在用于初始化example_container切片的复合字面量中,当列出元素时,甚至可以省略映射类型:

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

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",
	},
}

huangapple
  • 本文由 发表于 2017年1月12日 17:04:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/41608942.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定