はじめに
goでJSONの変換かけるのってホントめんどくさくないですか?
その中でも、
- 値を
null
にしたいんだけどどうすればいい? - 必要がない場合に、キーごと項目を落としたいんだけどどうすればいい?
というのでしばらく悩んでいたので、結果をまとめます。
Marshal関数のdoc block読んでも、自分はいまいち理解力がなくてよくわかりませんでした。
ロジックつくりつつ、こういう細かい部分もケアしつつ・・・とかやってるといろいろ混乱してしまいますね・・・。
特に複雑なAPIほど頭がモヤッとしてきます。
値を null
にしたい
*interface{}
(pointer)型の値にnil(正しくは interface{}(nil)
を渡してMarshalすればOK。
package main
import (
"encoding/json"
"fmt"
)
type SomeStruct struct {
Name string `json:"name,omitempty`
SomeID *interface{} `json:"some_id,omitempty"`
}
func main() {
a := SomeStruct{}
a.Name = "MyName"
thisIsNil := interface{}(nil)
a.SomeID = &thisIsNil
aBin, _ := json.Marshal(a)
fmt.Println(string(aBin))
}
実行してみます。
% go run main.go
{"Name":"MyName","some_id":null}
キーごと落としたい
interface{}
型の値に同じようにnilを渡してMarshalすればOK。
package main
import (
"encoding/json"
"fmt"
)
type SomeStruct struct {
Name string `json:"name,omitempty`
SomeID interface{} `json:"some_id,omitempty"`
}
func main() {
a := SomeStruct{}
a.Name = "MyName"
thisIsNil := interface{}(nil)
a.SomeID = thisIsNil
aBin, _ := json.Marshal(a)
fmt.Println(string(aBin))
}
実行すると、キー自体が存在しません。
% go run main.go
{"Name":"MyName"}
json merge patch的な動かし方をしたい場合に、予め型は決まっているけど差分じゃない部分は送ること自体をやめたい・・・みたいな処理が必要かと思いますが、これを使うことで対処できたんでホッとしました。