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

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

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

问题

示例代码:

  1. package main
  2. import "fmt"
  3. func main() {
  4. example_container := []interface{}{
  5. map[string]string{
  6. "name": "bob",
  7. "id": "1",
  8. },
  9. map[string]string{
  10. "name": "jim",
  11. "id": "2",
  12. },
  13. }
  14. fmt.Printf("%v\n", example_container)
  15. fmt.Printf("%v\n", example_container[0])
  16. fmt.Printf("%v\n", example_container[0]["name"])
  17. }

有问题的行:

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

错误:

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

问题:

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

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

英文:

Example code:

  1. package main
  2. import "fmt"
  3. func main() {
  4. example_container := []interface{}{
  5. map[string]string{
  6. "name": "bob",
  7. "id": "1",
  8. },
  9. map[string]string{
  10. "name": "jim",
  11. "id": "2",
  12. },
  13. }
  14. fmt.Printf("%v\n", example_container)
  15. fmt.Printf("%v\n", example_container[0])
  16. fmt.Printf("%v\n", example_container[0]["name"])
  17. }

Problematic line:

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

Error:

  1. 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来获取该映射类型的值,然后可以正确地进行索引:

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

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

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

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

  1. example_container := []map[string]string{
  2. map[string]string{
  3. "name": "bob",
  4. "id": "1",
  5. },
  6. map[string]string{
  7. "name": "jim",
  8. "id": "2",
  9. },
  10. }

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

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

Go Playground上尝试这个示例。

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

  1. example_container := []map[string]string{
  2. {
  3. "name": "bob",
  4. "id": "1",
  5. },
  6. {
  7. "name": "jim",
  8. "id": "2",
  9. },
  10. }
英文:

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:

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

Output (try it on the Go Playground):

  1. [map[name:bob id:1] map[name:jim id:2]]
  2. map[name:bob id:1]
  3. 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:

  1. example_container := []map[string]string{
  2. map[string]string{
  3. "name": "bob",
  4. "id": "1",
  5. },
  6. map[string]string{
  7. "name": "jim",
  8. "id": "2",
  9. },
  10. }

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

  1. 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:

  1. example_container := []map[string]string{
  2. {
  3. "name": "bob",
  4. "id": "1",
  5. },
  6. {
  7. "name": "jim",
  8. "id": "2",
  9. },
  10. }

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:

确定