2017-03-28 4 views
0

私はタイプMonthYearが、私は結果のJSONは、いずれかを持っていないように私はMonthYearタイプをインライン化するにはどうすればよいJSONをマーシャリングするときにフィールドをインライン化するにはどうすればよいですか?

type Event struct { 
    Name string `json:"name"` 
    Date MonthYear 
} 

type Item struct { 
    Category string `json:"category"` 
    Date  MonthYear 
} 

のような異なる構造体の多くのそれを含めてい

type MonthYear time.Time 

func (my *MonthYear) MarshalJSON() ([]byte, error) { 
    t := time.Time(*my) 

    return json.Marshal(&struct { 
     Month int `json:"month"` 
     Year int `json:"year"` 
    }{ 
     Month: int(t.Month()) - 1, 
     Year: t.Year(), 
    }) 
} 

のように定義されています埋め込みオブジェクト?

結果は、構造体ごとにMarshalJSONを記述することなく、{ "name": "party", "month": 2, "year": 2017 }および{ "category": "art", "month": 3, "year": 2016 }のようになります。

+0

ブラッドフィッツパトリックの答えがあなたのために十分でない場合、私は何か分かりません。 https://github.com/golang/go/issues/6213 – Zoyd

+0

もしあなたがスーパーであれば、マーシャルのJSON関数 –

答えて

3

私は、これはあなたが受け取ることを望む答えではないですけど、インラインサポートがencoding/jsonパッケージに追加されるまで、あなたは次の回避策を使用することがあります:

例えば、あなたのMonthYear構造体を作成します。

type MonthYear struct { 
    t  time.Time 
    Month int `json:"month"` 
    Year int `json:"year"` 
} 

簡単に作成するためのオプション、コンストラクタ関数:

func NewMonthYear(t time.Time) MonthYear { 
    return MonthYear{ 
     t:  t, 
     Month: int(t.Month()) - 1, 
     Year: t.Year(), 
    } 
} 

と使用embedding(匿名フィールド)の代わりにO F通常の(名前の)フィールドは、JSON表現にインライン化/「フラット化」を取得します

type Event struct { 
    Name string `json:"name"` 
    MonthYear 
} 

type Item struct { 
    Category string `json:"category"` 
    MonthYear 
} 

余分として、あなたは直接Event.YearかいいですEvent.Monthのようなフィールドを参照できるようになります。

それをテストする:

evt := Event{Name: "party", MonthYear: NewMonthYear(time.Now())} 
fmt.Println(json.NewEncoder(os.Stdout).Encode(evt), evt.Year) 

itm := Item{Category: "Tool", MonthYear: NewMonthYear(time.Now())} 
fmt.Println(json.NewEncoder(os.Stdout).Encode(itm)) 

出力は(Go Playground上でそれを試してみてください):

{"name":"party","month":10,"year":2009} 
<nil> 2009 
{"category":"Tool","month":10,"year":2009} 
<nil> 

注:MonthYear.t時間フィールドは、ここで役割を果たしていない(それはどちらかのマーシャリングされません)。元のtime.Timeが不要な場合は、削除することができます。

関連する問題