【问题标题】:How to assert a primitive.m to a map[string]string如何将primitive.m断言到map[string]string
【发布时间】:2020-08-04 20:49:03
【问题描述】:

我在我的 Go 应用程序中使用 MongoDB,并提取一些数据并将其存储在 bson.M 中(这是一个示例,从数据库中获取 bson.M 对象然后打印它(让我们调用这个对象data):

[map[_id:ObjectID("XXXXXXX") address:XX decimal:18 providers:map[currency:value] symbol:LINK]

这对我来说是正确的。

我想循环遍历providers 字段中的地图(如您所见,它也是其中的地图)。我做了几次尝试,但每次都被阻止。

由于我在docs here 中阅读的内容以及我所做的测试,看起来 bson.M 和primitive.M 是相同的,它们都被视为map[string]interface{}

当我尝试将其声明为 map[string]string 时,我出现了一个恐慌错误:

// code run
data["providers"].(map[string]string)

//error received
panic: interface conversion: interface {} is primitive.M, not map[string]string

原因是我想遍历providers 字段,当我尝试按原样循环时,我收到此错误:

// code to run
for key, provider := range data["providers"] {...}

// error received
cannot range over data["providers"] (map index expression of type interface{})

我读到我可能需要对编组和解码做一些事情,但我觉得我只是错过了一个步骤,为什么我需要这样做,或者他们将如何提供帮助。

无论如何总结一下:

  1. 如何循环遍历primitive.M/bson.M/map[string]interface{}?

  2. 如何将 primitive.M/bson.M/map[string]interface{} 转换为 map[string]string?

看起来我可能试图做与this entry 相反的事情,而且看起来this entry 给了我相互矛盾的信息。希望在我了解更多我的真正问题时编辑问题。谢谢!

【问题讨论】:

    标签: mongodb go casting


    【解决方案1】:

    与 Burak Serdar 交谈帮助我们找到了答案!您必须将 data["providers"] 断言为 primitive.M

    for key, provider := range data["providers"].(primitive.M){...}
    

    需要注意的关键点:primitive.M 的处理方式类似于 map[string]interface{}

    正如 Burak Serdar 所提到的,我不能将 Primitive.M 的这个实例断言为 map[string]string,因为map[string]interface{} 中的interfaceprimitive.M 类型。所以相反,我必须将providers 对象断言为primitive.M 对象,然后我可以正常循环它。

    我无法将primitive.M 转换为map[string]string

    【讨论】:

      【解决方案2】:

      map[string]interface{}map[string]string 的类型断言将失败,因为它是类型断言,而不是类型转换。它只检查接口类型是否是您认为的那样,在这种情况下,它不是。您必须迭代 map[string]interface{},然后对值进行类型断言:

      for k,v:=range data.(primitive.M)["providers"] {
         if str, ok:=v.(string); ok {
            // Use k and str
         }
      }
      

      【讨论】:

      • 当我尝试时它没有达到“if”语句,我仍然得到cannot range over data["providers"] (type interface {})。我应该在运行循环之前将数据转换为其他内容吗?
      • 数据是primitive.M吗?如果是这样,请尝试上面的编辑版本
      • 啊,几乎成功了!所以事实证明你必须做data["providers"].(primitive.M)(接近你所拥有的)然后你不必键入断言值,尽管我不知道为什么。我认为这是因为数据对象中的提供者对象可以被断言为原语.M 而不是映射,因为这就是它的接口。我将添加一个问题的答案来澄清。感谢您的帮助!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-17
      • 1970-01-01
      相关资源
      最近更新 更多