最近なんだか疲れてて、ブログもあまり書けてないけど、なんとかやめずに続けてきたい。。
ここのところはGoでWebアプリを作ろうとしてちょっとずつやってる。
Goは標準ライブラリが充実してるし、勉強のためにもできるだけフレームワーク無しで作ってみたいと思ってる。
今回はアプリ内部で使うapiを作ってるときに調べたことのメモ
なにがしたいか?
1
2
3
4
5
6
7
8
9
10
11
12
|
type Something struct {
HappenedAt time.Time
HappenedDate time.Time
}
func main() {
js, _ := json.Marshal(something)
fmt.Println(string(js))
}
# 実行結果
{"HappenedAt":"2020-02-07T00:25:09.209870352+09:00","HappenedDate":"2020-02-07T00:25:09.209870648+09:00"}
|
こんなふうにstructをjsonにする際に、デフォルトだと
HappenedAtもHappenedDateも完全な時間がでちゃいますね。
これをDateの方は、2020-02-07とだけしたい。
解決策
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
type Date time.Time
func (date Date) MarshalJSON() ([]byte, error) {
return []byte(`"` + time.Time(date).Format("2006-01-02") + `"`), nil
}
type Something struct {
HappenedAt time.Time
HappenedDate Date
}
func main() {
something := Something{
HappenedAt: time.Now(),
HappenedDate: Date(time.Now()),
}
js, _ := json.Marshal(something)
fmt.Println(string(js))
}
# 実行結果
{"HappenedAt":"2020-02-07T00:41:40.816646918+09:00","HappenedDate":"2020-02-07"}
|
type
type表現をつかうと、structや型などに別名をつけることができます。
別名をつけると元のstructとは別のものとして扱われ、メソッドを追加したりオーバーライドすることができます。
time.TimeにDateという別名をつけ、json.Marshal()するときに呼ばれるMarshalJSONというメソッドをオーバーライドすることで、好きなようにフォーマット等を書き換えることができます。
メソッドの継承・・・はできないので
ただ、注意としてtypeで別名をつけたstructは元のstructのメソッドを継承しません。
だから、MarshalJSONも正確にはオーバーライドではなく新しくメソッドを作っているイメージ。
メソッドを継承しないので、Date.Format("...")
のようにしてtime.TImeのメソッドをそのまま使うことができない。
元structのメソッドを使いたいときには、一旦元structにキャストする。
1
|
time.Time(date).Format("2006-01-02")
|
おわり
golangには継承の概念がないからこのあたり独特ですね。