MarshalJSON bug?

1,433 views
Skip to first unread message

John DeNero

unread,
Dec 27, 2011, 9:36:25 PM12/27/11
to golang-nuts
Should the following MarshalJSON example work? If so, I'll file a bug.
If not, what am I doing wrong in implementing a custom marshal
function that writes only a single field of a struct? I get:

panic: json: error calling MarshalJSON for type main.S: invalid
character 'N' looking for beginning of value

package main

import (
"encoding/json"
"math"
)

type S struct {
fs []float64
}

func (s S) MarshalJSON() ([]byte, error) {
return json.Marshal(s.fs)
}

func main() {
s := S{[]float64{math.NaN()}}
b, err := json.Marshal(s)
if err != nil {
panic(err)
}
println(string(b))
}

Thanks,
John

Evan Shaw

unread,
Dec 28, 2011, 12:13:41 AM12/28/11
to John DeNero, golang-nuts

I don't think you're doing anything wrong implementing json.Marshaler.

I suspect the problem is that the JSON spec doesn't define an NaN
value (or infinity), but the Go package is using strconv internally,
which handles NaN. Trying to marshal any value containing NaN,
infinity, or -infinity should probably return an error.

- Evan

John DeNero

unread,
Dec 28, 2011, 12:44:47 AM12/28/11
to golang-nuts
I see. It seems that some other JSON encoders offer a flag to allow
non-strict JSON that includes NaN & Inf. E.g., http://pypi.python.org/pypi/simplejson/

In any case, I agree that Marshal should error on non-finite floats.
The following round trip doesn't work, which perhaps happened
implicitly somewhere in my previous example.

func main() {
f1 := math.NaN()
b, err := json.Marshal(f1)
if err != nil {
panic(err)
}
var f2 float64
err = json.Unmarshal(b, &f2)
if err != nil {
panic(err)
}
println(f1, f2)
Reply all
Reply to author
Forward
0 new messages