2013-06-05 2 views
10

:ここGo言語では、jsonをオブジェクトの配列にアンマーシャリングするにはどうすればよいですか?私は、次のJSONを持っている、と私はクラスの配列にそれを解析したい

{ 
    "1001": {"level":10, "monster-id": 1001, "skill-level": 1, "aimer-id": 301} 
    "1002": {"level":12, "monster-id": 1002, "skill-level": 1, "aimer-id": 302} 
    "1003": {"level":16, "monster-id": 1003, "skill-level": 2, "aimer-id": 303} 
} 

は私がやろうとしていますものですが、失敗しました:

type Monster struct { 
    MonsterId int32 
    Level  int32 
    SkillLevel int32 
    AimerId int32 
} 


type MonsterCollection struct { 
    Pool map[string]Monster 
} 

func (mc *MonsterCollection) FromJson(jsonStr string) { 
    var data interface{} 
    b := []byte(jsonStr) 
    err := json.Unmarshal(b, &data) 
    if err != nil { 
     return 
    } 

    m := data.(map[string]interface{}) 

    i := 0 
    for k, v := range m { 

     monster := new(Monster) 
     monster.Level = v["level"] 
     monster.MonsterId = v["monster-id"] 
     monster.SkillLevel = v["skill-level"] 
     monster.AimerId = v["aimer-id"] 

     mc.Pool[i] = monster 
     i++ 
    } 

} 

コンパイラはV文句を言います["レベル"] < <無効な操作です。タイプinterface()のインデックス。

答えて

18

このコードには多くのエラーがあります。まず、jsonは有効なjsonではありません。トップレベルオブジェクトのキーペアの間にカンマがありません。私はカンマを追加し、かなりあなたのためにそれを印刷:

{ 
    "1001":{ 
     "level":10, 
     "monster-id":1001, 
     "skill-level":1, 
     "aimer-id":301 
    }, 
    "1002":{ 
     "level":12, 
     "monster-id":1002, 
     "skill-level":1, 
     "aimer-id":302 
    }, 
    "1003":{ 
     "level":16, 
     "monster-id":1003, 
     "skill-level":2, 
     "aimer-id":303 
    } 
} 

あなたの次の問題(あなたがについて尋ねたもの)m := data.(map[string]interface{})map[string]interface{}mを作るということです。つまり、範囲ループ内にvなどのインデックスを付けると、タイプはinterface{}となります。 v.(map[string]interface{})で再度それをアサートし、マップから読み込むたびにassertとタイプする必要があります。


私はまた、あなたのことを私はint型であるとmc.Poolはマップ[文字列]モンスターである次の試みmc.Pool[i] = monsterに気づきます。 intはそのマップの有効なキーではありません。


あなたのデータは非常に堅く見えますので、私はunmarshallにあなたの仕事のほとんどを行います。 map [string]インタフェース{}を提供する代わりに、map [string] Monsterを提供することができます。

ここは簡単な例です。アンマーシャリングの仕方を変更するだけでなく、エラーリターンも追加しました。エラーリターンは、バグを見つけるのに便利です。そのエラーリターンはあなたに無効なjsonがあると私に言ったものです。

type Monster struct { 
    MonsterId int32 `json:"monster-id"` 
    Level  int32 `json:"level"` 
    SkillLevel int32 `json:"skill-level"` 
    AimerId int32 `json:"aimer-id"` 
} 

type MonsterCollection struct { 
    Pool map[string]Monster 
} 

func (mc *MonsterCollection) FromJson(jsonStr string) error { 
    var data = &mc.Pool 
    b := []byte(jsonStr) 
    return json.Unmarshal(b, data) 
} 

私はgoplayに作業例を掲載:やや片側にオフhttp://play.golang.org/p/4EaasS2VLL

+0

うわー、ありがとうございます。私はGO langを勉強しているだけでなく、まだ多くのことを学んでいます。あなたの答えはとても役に立ちます! – Nick

+0

もう1つ質問がありますが、とにかく地図のキーにint32を使用できますか?値はmonster-idでなければなりません。この場合ですが、型をint32に変更すると、サンプルコードでエラーが発生します。 – Nick

+3

JSONキーは文字列でなければなりません。あなたがしなければならないことは、最初に '' map [string] Monster''をパースし、 '' map [int]モンスターに各モンスターをコピーすることです。 –

関連する問題