encoding/json behavior with *int64 and string tag option

268 views
Skip to first unread message

Matt Duch

unread,
Jul 19, 2014, 11:41:52 PM7/19/14
to golan...@googlegroups.com
After working with the json package for a while I've run into some behavior I was curious about, sample code:

package main

import (
"fmt"
"encoding/json"
)

type myObj struct {
Id   *int64  `json:"id,string"`
}
func main() {
id := int64(1)
obj := &myObj{Id: &id}
b, err := json.Marshal(obj)
if err != nil {
fmt.Println("err marshalling", err)
return
}
fmt.Println("json:", string(b))
newObj := &myObj{}
err = json.Unmarshal(b, newObj)
if err != nil {
fmt.Println("err unmarshalling", err)
return
}
}

Which produces the output:
json: {"id":1}
err unmarshalling json: cannot unmarshal number into Go value of type string

Which is unfortunate, since the same struct can't be used to encode and decode the same data (unless I'm missing something).

After digging around in the source I ran into the encoder for this situation:
func (pe *ptrEncoder) encode(e *encodeState, v reflect.Value, _ bool) {
if v.IsNil() {
e.WriteString("null")
return
}
pe.elemEnc(e, v.Elem(), false)
}

I'm curious as to why this flag is ignored in pointers (and results in behavior different from the decode case). I noticed that the array, slice, struct, and map encoders ignore this value, so that behavior wouldn't change if the quoted parameter was passed through to the element's encoder. 

Matt

ancientlore

unread,
Aug 8, 2014, 5:07:47 PM8/8/14
to golan...@googlegroups.com
I have the same issue - it seems like the "string" option could apply to pointers, but it doesn't.
Reply all
Reply to author
Forward
0 new messages