2

私のコードは、次のような関数で埋め尽くされています:

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 できます。これを行う一般的な方法はありますか?クラスごとに1つの関数を書く必要はありませんか? 私は次のようなことを試みました:

type Int64JSON int64 `json:",string"`

元のマップで Int64JSON を使用していますが、コンパイラは型定義の json タグを好みません:(

よろしくお願いします!

4

2 に答える 2

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
}

遊び場

于 2013-09-25T13:35:09.193 に答える
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   
}

(プレイ中)

リフレクションなどを使用することもできます。

とはいえ、それを行う前に、実際の型に対してそれを行うのが本当に負担になるかどうかを考えます。適切な型付けを行うことにはいくつかの利点があり (型チェック、読み取り時のアサーションが不要、パフォーマンス、メモリ使用量など)、コード量もかなり少なくなります。

于 2013-09-24T16:54:47.690 に答える