2

How do ensure the fields in this LookupCode struct are included when marshalling?

package main

import (
    "encoding/json"
    "fmt"
)

type LookupCode struct {
    code string `json:"code"`
    name string `json:"name"`
}

func (l *LookupCode) GetCode() string {
    return l.code
}

func main() {
    c := &LookupCode{
        code: "A",
        name: "Apple",
    }

    b, _ := json.MarshalIndent(c, "", "\t")

    fmt.Println(string(b))
}

http://play.golang.org/p/my52DAn0-Z

Jay
  • 19,649
  • 38
  • 121
  • 184
  • 1
    possible duplicate of [golang json and dealing with unexported fields](http://stackoverflow.com/questions/11126793/golang-json-and-dealing-with-unexported-fields) – OneOfOne Aug 20 '14 at 00:11

3 Answers3

7

You can by implementing the json.Marshaller interface:

Full Example: http://play.golang.org/p/8mIcPwX92P

// Implement json.Unmarshaller
func (l *LookupCode) UnmarshalJSON(b []byte) error {
    var tmp struct {
        Code string `json:"code"`
        Name string `json:"name"`
    }
    err := json.Unmarshal(b, &tmp)
    if err != nil {
        return err
    }
    l.code = tmp.Code
    l.name = tmp.Name
    return nil 
}

func (l *LookupCode) MarshalJSON() ([]byte, error) {
    return json.Marshal(struct {
        Code string `json:"code"`
        Name string `json:"name"`
    }{
        Code: l.code,
        Name: l.name,
    })
}
fabrizioM
  • 46,639
  • 15
  • 102
  • 119
  • 1
    Minor point, but since the fields of `LookupCode` are unexported and thus not used by the json package, the struct tags aren't actually used for anything, and they can (and should) be removed. – joshlf Aug 20 '14 at 00:36
5

encode/json cannot marshal unexported fields. Change your code to:

type LookupCode struct {
    Code string `json:"code"`
    Name string `json:"name"`
}

and do the same wherever you use code or name.

Playground: http://play.golang.org/p/rak0nVCNGI

Edit

The limitation is due to the reflection used when marshalling the struct. If you need to keep your values unexported, you must implement the json.Marshaller interface and do the encoding manually.

ANisus
  • 74,460
  • 29
  • 162
  • 158
0

if the struct has only string-type fields,you can try this hack way.

package main

import (
    "fmt"
    "reflect"

    "github.com/bitly/go-simplejson"
)

type A struct {
    name string `json:"name"`
    code string `json:"code"`
}

func marshal(a A) ([]byte, error) {
    j := simplejson.New()
    va := reflect.ValueOf(&a)
    vt := va.Elem()
    types := reflect.TypeOf(a)
    for i := 0; i < vt.NumField(); i++ {
        j.Set(types.Field(i).Tag.Get("json"), fmt.Sprintf("%v", reflect.Indirect(va).Field(i)))
    }
    return j.MarshalJSON()
}

func main() {
    a := A{name: "jessonchan", code: "abc"}
    b, _ := marshal(a)
    fmt.Println(string(b))
}
JessonChan
  • 216
  • 2
  • 3