【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脳ですみません。。。)

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA