【Go】privateの構造体をjson.Marshalした時に空でreturnされる
概要
同package内でのみアクセスできる(private)構造体を json.Marshal した時に戻り値が空になる。
事象
privateの構造体を用意する
package pkg type User struct { id string name string token string } func (u User) GetId() string { return u.id } func (u User) GetName() string { return u.name } func (u User) GetToken() string { return u.token } func New(id, name, token string) *User { return &User{id, name, token} }
対象の構造体(User.go)をjson.Marshalする。
package main import ( "encoding/json" "fmt" "work/pkg" ) func main() { user := pkg.New("0001", "test-user", "abcdefg") fmt.Println(user) userjson, err := json.Marshal(&user) if err != nil { fmt.Errorf("error marshal:", err) } fmt.Println(string(userjson)) }
実行結果は以下の通り、空で出力される
&{0001 test-user abcdefg} {}
なんとなく察してはいたけれどjson.Marshalはprivateな値は対象にしてくれない模様…
先頭文字を直してpublicにしようか迷ったがオブジェクト指向っぽく作りたかったため
今回はMarshalJSONで誤魔化す事にした。
package pkg import "encoding/json" type User struct { id string name string token string } func (u User) GetId() string { return u.id } func (u User) GetName() string { return u.name } func (u User) GetToken() string { return u.token } func New(id, name, token string) *User { return &User{id, name, token} } /* json.Marshalする時に各項目をGetする処理を追加 */ func (u *User) MarshalJSON() ([]byte, error) { v, err := json.Marshal(&struct { Id string Name string Token string }{ Id: u.GetId(), Name: u.GetName(), Token: u.GetToken(), }) return v, err }
再度、実行する
&{0001 test-user abcdefg} {"Id":"0001","Name":"test-user","Token":"abcdefg"}
所感
値にjsonパラメータを設定する際にprivateでも取得できる様な設定方法があるのかは随時調査して行く予定です。
jsonに変換する構造体自体をpublicで作るべきなのかは、正直分からず…
もっといい実装方法をご存知の方がいらっしゃいましたら教えて頂けると幸いです。
そもそもGoではパッケージ外部からアクセスできない構造体をprivateと読んでいいのかも謎です。 (java脳ですみません。。。)