2017-08-03 13 views
0

私は新しい宣言された型を作成し、私は生の値が返され得るタイプのインスタンスをマーシャリングしようとするとJSONMarshalJSON文字列宣言された型

type TextOutput string 

func (t *TextOutput) MarshalJSON() ([]byte, error) { 
    return []byte(fmt.Sprintf(`{"data": "%s"}`, t)), nil 
} 

に値をマーシャリングする方法を追加しました。私は何が欠けていますか?

var t TextOutput 
t = `Test test` 
output, err := json.Marshal(t) 
if err != nil { 
    fmt.Println(err) 
} else { 
    fmt.Println(string(output)) 
} 
// prints Test Test. Expected {"data": "Test test"} 
+1

あなたの 'UnmarshalJSON'メソッドはどこにありますか? – Flimzy

答えて

1

問題の根本は、移動中のインタフェースが暗黙的に満たされているかに由来します。
この特定のケースでは、json.Marshalメソッドは実行時に型アサーションを使用して、指定された値がjson.Marshalerを実装しているかどうかを確認します。有効な終了mentions this very case

あなたがそうのようなポインタ、受信機使用*TextOutputタイプにjson.Marshalerを満たしている可能性:json.Marshal関数への参照を渡し、

func (t *TextOutput) MarshalJSON() ([]byte, error) { 
    return []byte(fmt.Sprintf(`{"data":"%s"}`, *t)), nil 
} 

そして、これが正しく動作するために:

var t TextOutput 
t = `Test test` 
output, err := json.Marshal(&t) 

しかし、バリューレシーバを使用して実装すると、TextOutput*TextOutputの両方のタイプが実装されます。json.Marshaler

func (t TextOutput) MarshalJSON() ([]byte, error) { 
    return []byte(fmt.Sprintf(`{"data": "%s"}`, t)), nil 
} 
2

MarshalJSONインターフェイスを非ポインタとして定義する必要があります。

func (t TextOutput) MarshalJSON() ([]byte, error) { 
    return []byte(fmt.Sprintf(`{"data": "%s"}`, t)), nil 
} 

プレイリンク:https://play.golang.org/p/lLK6zsAkOi

出力:

{"data":"Test test"} 
関連する問題