使用go,如何将map [int] T转换为map [string] T与JSON一起使用?

时间:2013-09-24 15:51:21

标签: json go

我的代码贴满了以下功能:

func TransformMapClassA(mapOfIntToClassA map[int]*ClassA) map[string]*ClassA {
  mapOfStringToClassA := make(map[string]*ClassA)
  for id, obj := range mapOfIntToClassA {
    mapOfStringToClassA[fmt.Sprintf("%d" obj.Id)] = obj
  }
  return mapOfStringToClassA
}

在我的申请中为每个班级写了一次。我这样做,所以我可以json.Marshal现有的地图。有没有通用的方法,所以我不必每个类写一个函数?我尝试过这样的事情:

type Int64JSON int64 `json:",string"`

在原始地图中使用Int64JSON,但编译器不喜欢类型定义中的json标记:(

非常感谢提前!

2 个答案:

答案 0 :(得分:2)

如果您仍想使用反射创建一个从任何类型的地图返回map [string] interface {}的函数,您可以执行以下操作:

func TransformMap(m interface{}) (map[string]interface{}, error) {

    v := reflect.ValueOf(m)

    if v.Kind() != reflect.Map {
        return nil, errors.New("Map required")
    }

    result := make(map[string]interface{}, v.Len())

    keys := v.MapKeys()
    for _, k := range keys {
        result[fmt.Sprint(k.Interface())] = v.MapIndex(k).Interface()
    }

    return result, nil
}

Playground

答案 1 :(得分:1)

有很多方法可以做到这一点。其中一个是使用通用map[interface{}]interface{},并具有转换功能,如:

func stringMap(m map[interface{}]interface{}) map[string]interface{} {
    result := make(map[string]interface{})
    for k, v := range m {
        result[fmt.Sprint(k)] = v
    }
    return result   
}

(在play上)

您也可以使用反射等

那就是说,在做任何这样的事情之前,我会思考为真正的类型做这件事是否真的太重了。正确输入(类型检查,读取时不需要断言,性能,内存使用等)有几个好处,而且代码量相当少。