2016-07-05 16 views
3

タイプmap[mapKey]stringのマップをgobエンコーダを使用してファイルに保存しようとすると、ファイル内に文字列が保存されません。ゴブを使用してファイルに正しくデータを保存できません

ここでmapKeyは構造体であり、マップ値は長いjson文字列です。

type mapKey struct{ 
    Id1 string 
    Id2 string 
} 

そして時はいつでも、私は次のように代わりに構造体のネストされたマップを使用しています:それは正常に動作し、適切に文字列を保存している

var m = make(map[string]map[string]string) 

。私はここで何が欠けているのか分かりません。

コードは、エンコード、デコードおよびファイルに保存するには:タイプmap[mapKey]stringの値を符号化する中で特別なものは何もありません

func Save(path string, object interface{}) error { 
    file, err := os.Create(path) 
    if err == nil { 
     encoder := gob.NewEncoder(file) 
     encoder.Encode(object) 
    } 
    file.Close() 
    return err 
} 

// Decode Gob file 
func Load(path string, object interface{}) error { 
    file, err := os.Open(path) 
    if err == nil { 
     decoder := gob.NewDecoder(file) 
     err = decoder.Decode(object) 
    } 
    file.Close() 
    return err 
} 

func Check(e error) { 
    if e != nil { 
     _, file, line, _ := runtime.Caller(1) 
     fmt.Println(line, "\t", file, "\n", e) 
     os.Exit(1) 
    } 
} 
+1

そして、なぜあなたはとして使用していませんネストされたマップ。おそらく、入力はネストされたマップである必要があります。 –

+0

@SimoEndre:https://blog.golang.org/go-maps-in-actionブログでは、マッピング用にネストされたマップタイプの構造がある場合は、Structを使用することをおすすめします。 しかし、私は新しくGoです。構造体を使用できるかどうかはわかりません。 コンパイルエラーは発生していませんが、長い文字列は保存されていません。 – rohan

答えて

4

指定されたリーダ/ライタを使用して、この非常に単純な作業の例を参照してください:

func save(w io.Writer, i interface{}) error { 
    return gob.NewEncoder(w).Encode(i) 

} 
func load(r io.Reader, i interface{}) error { 
    return gob.NewDecoder(r).Decode(i) 
} 

テストも、インメモリバッファ(bytes.Buffer)で:

m := map[mapKey]string{ 
    {"1", "2"}: "12", 
    {"3", "4"}: "34", 
} 
fmt.Println(m) 

buf := &bytes.Buffer{} 
if err := save(buf, m); err != nil { 
    panic(err) 
} 

var m2 map[mapKey]string 
if err := load(buf, &m2); err != nil { 
    panic(err) 
} 
fmt.Println(m2) 

期待通りの出力が(それを試してみてくださいGo Playground):

map[{1 2}:12 {3 4}:34] 
map[{1 2}:12 {3 4}:34] 

あなたは仕事がありますあなたはポインタ値でLoad()を呼び出さなければならないことを知っています(そうでなければDecoder.Decode()はその値を変更できません)。

また、それを改善するためのいくつかのこと:あなたの例では

  • あなたは(それをチェックEncoder.Encode()によって返さerrorを嚥下され、あなたはどのような問題がある参照してくださいよ、構造体を使用している共通の問題mapKeyエクスポートされたフィールドがない場合は、gob: type main.mapKey has no exported fieldsのエラーが返されます)。
  • また、遅延機能としてFile.Close()を呼び出す必要があります。
  • また、ファイルを開くのに失敗した場合は、早めに戻ってファイルを閉じるべきではありません。

これはあなたのコードの修正版です:

func Save(path string, object interface{}) error { 
    file, err := os.Create(path) 
    if err != nil { 
     return err 
    } 
    defer file.Close() 
    return gob.NewEncoder(file).Encode(object) 
} 

func Load(path string, object interface{}) error { 
    file, err := os.Open(path) 
    if err != nil { 
     return err 
    } 
    defer file.Close() 
    return gob.NewDecoder(file).Decode(object) 
} 

テストそれ:予想通り

m := map[mapKey]string{ 
    {"1", "2"}: "12", 
    {"3", "4"}: "34", 
} 
fmt.Println(m) 

if err := Save("testfile", m); err != nil { 
    panic(err) 
} 

var m2 map[mapKey]string 
if err := Load("testfile", &m2); err != nil { 
    panic(err) 
} 
fmt.Println(m2) 

が出力:

map[{1 2}:12 {3 4}:34] 
map[{1 2}:12 {3 4}:34] 
+0

ここで説明されているiczaとしてポインタを使用しているかどうかを確認することをお勧めします。 – TehSphinX

関連する問題