将map[interface{}]interface{}转换为map[string]string

45
我收到一个数据地图,它是以 map[interface {}]interface {} 的形式呈现的,而我无法影响数据来源。我需要处理其中的数据,并将其转换为 map[string]string 格式(其中的数据非常适合该格式)。此外,我还需要生成数据中包含的键的列表,因为这些键事先是未知的。在网络上,我找到了类似的问题,大多数说这是不可能的,但如果我的地图是 mfmt.Println(m) 可以显示出数据,并且可以读取为 map[k0:v0 K1:v1 k2:v2 ... ] 的格式。那么我该如何做到像 fmt.Println 一样的操作呢?

1
当然,数据是存在的,你只需要遍历地图。无法直接转换这些结构。 - JimB
1
可能是在Go中将接口切片转换类型的重复问题。 - JimB
我想我必须重新提问。我得到的地图拒绝迭代,而@Swoogan的答案完美地工作。 - user3160501
3个回答

31

一个安全的处理未知接口的方法,只需要使用fmt.Sprintf()。

https://play.golang.org/p/gOiyD4KpQGz

package main

import (
    "fmt"
)

func main() {

    mapInterface := make(map[interface{}]interface{})   
    mapString := make(map[string]string)

    mapInterface["k1"] = 1
    mapInterface[3] = "hello"
    mapInterface["world"] = 1.05

    for key, value := range mapInterface {
        strKey := fmt.Sprintf("%v", key)
        strValue := fmt.Sprintf("%v", value)

        mapString[strKey] = strValue
    }

    fmt.Printf("%#v", mapString)
}

18

也许我误解了问题,但是这个方法可行吗?

m := make(map[interface{}]interface{})
m["foo"] = "bar"

m2 := make(map[string]string)   

for key, value := range m {        
    switch key := key.(type) {
    case string:
        switch value := value.(type) {
        case string:
            m2[key] = value
        }
    }
}

6
了解,您可以在switch语句中进行变量赋值,因此不需要进行类型断言:http://play.golang.org/p/-ZeUXTKu9a - JimB
对不起,在我急于回答的时候可能忽略了这一点。谢谢! - Swoogan
谢谢!这是我最初尝试的方法,但失败了。您的示例确实有效,而“我的”映射由于类型接口{}而拒绝范围。两者都被reflect.TypeOf报告为“map [interface {}] interface {}”,但行为不同....??? - user3160501
@user3160501:通过将map[interface{}]interface{}作为interface{}传递,你可能进一步混淆了问题。听起来你需要在这里进行另一种类型断言,但如果你想得到帮助,你需要展示一个例子。 - JimB
@JimB:听起来你指出了一个很有帮助的方向,虽然我还没有找到在我的代码中发生这种情况的地方,也不知道如何包装一个好的例子。但我会尝试后者! - user3160501

0

// data is map[string]interface{}

form := make(map[string]string)

for k, v := range data {
    form[k] = v.(string)
}


2
这个问题的输入是 map[interface{}]interface{},而不是 map[string]interface{} - Arnie97

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接