I have a data structure which uses maps with unusual key types (structs, but the problem can be illustrated with any type); I want to marshal it to JSON.
$ go version
go version go1.6.2 linux/amd64
JSON does not allow arbitrary objects to be used as map keys. One workaround, according Go’s encoding/json package, is
The map’s key type must either be a string, an integer type, or implement encoding.TextMarshaler.
I tried it the third option:
package main
import (
"fmt"
"encoding/json"
)
type Int int
func (i Int) MarshalText() (text []byte, err error) {
return []byte("int"), nil
}
func main() {
m := make(map[Int]int)
m[Int(42)] = -19
b, err := json.Marshal(m)
if err != nil {
panic(err)
}
fmt.Println(string(b))
}
and I get
panic: json: unsupported type: map[main.Int]int
I find it strange that the map type as a whole is reported as the problem rather than the type of its key. The encoding/json documentation implies that maps are supported insofar as their keys implement encoding.TextMarshaler.
I have also tried implementing the json.Marshaler interface:
The feature you are referring to was added in Go 1.7. (Which @nathankerr was strongly hinting at by asking about your version and showing that it works in the current stable one. )
Having worked for Canonical I can tell you with certainty that their version will always be out of date.
I strongly recommend using the Go binaries distributed from the Go project itself. They are always up to date, extremely well tested, and known to work on a wide array of operating systems.