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