Reviewers:
golang-dev_googlegroups.com,
Message:
Hello
golan...@googlegroups.com (cc:
golang...@googlegroups.com,
golan...@googlegroups.com),
I'd like you to review this change to
https://code.google.com/p/go
Description:
encoding/json: Marshal a map with numeric keys.
Json package only accept a string keys map to encode currently.
There will be an error when encoding a map with numeric keys.
Eg. [
http://play.golang.org/p/11oo0H0NtE]
got "json: unsupported type: map[int]string"
In developing, it is common that using a map with numeric keys.
Then we must copy & convert numbers into strings befor encoding into
json.
It is not convenient.
This patch was created for encoding the map with numeric keys into json.
Sorry for my English. Hope I have explained it clearly.
Please review this at
http://codereview.appspot.com/6338067/
Affected files:
M src/pkg/encoding/json/encode.go
M src/pkg/encoding/json/encode_test.go
Index: src/pkg/encoding/json/encode.go
===================================================================
--- a/src/pkg/encoding/json/encode.go
+++ b/src/pkg/encoding/json/encode.go
@@ -350,7 +350,11 @@
e.WriteByte('}')
case reflect.Map:
- if v.Type().Key().Kind() != reflect.String {
+ k := v.Type().Key().Kind()
+ if k != reflect.String && k != reflect.Uint && k != reflect.Uint16 &&
+ k != reflect.Uint32 && k != reflect.Uint64 &&
+ k != reflect.Uint8 && k != reflect.Int && k != reflect.Int16 &&
+ k != reflect.Int32 && k != reflect.Int64 && k != reflect.Int8 {
e.error(&UnsupportedTypeError{v.Type()})
}
if v.IsNil() {
@@ -364,7 +368,7 @@
if i > 0 {
e.WriteByte(',')
}
- e.string(k.String())
+ e.string(sv.get(i))
e.WriteByte(':')
e.reflectValue(v.MapIndex(k))
}
@@ -447,7 +451,19 @@
func (sv stringValues) Len() int { return len(sv) }
func (sv stringValues) Swap(i, j int) { sv[i], sv[j] = sv[j], sv[i] }
func (sv stringValues) Less(i, j int) bool { return sv.get(i) < sv.get(j) }
-func (sv stringValues) get(i int) string { return sv[i].String() }
+func (sv stringValues) get(i int) (r string) {
+ switch sv[i].Kind() {
+ case reflect.String:
+ r = sv[i].String()
+ case reflect.Uint, reflect.Uint16, reflect.Uint32,
+ reflect.Uint64, reflect.Uint8:
+ r = strconv.Itoa(int(sv[i].Uint()))
+ case reflect.Int, reflect.Int16, reflect.Int32,
+ reflect.Int64, reflect.Int8:
+ r = strconv.Itoa(int(sv[i].Int()))
+ }
+ return
+}
func (e *encodeState) string(s string) (int, error) {
len0 := e.Len()
Index: src/pkg/encoding/json/encode_test.go
===================================================================
--- a/src/pkg/encoding/json/encode_test.go
+++ b/src/pkg/encoding/json/encode_test.go
@@ -26,6 +26,19 @@
Mo map[string]interface{} `json:",omitempty"`
}
+var mapNumIndexExpected = `{"0":0,"2":"","4":null}`
+
+func TestMapNumberIndex(t *testing.T) {
+ m := map[int]interface{}{0: 0, 2: "", 4: nil}
+ got, err := Marshal(m)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if got := string(got); got != mapNumIndexExpected {
+ t.Errorf(" got: %s\nwant: %s\n", got, mapNumIndexExpected)
+ }
+}
+
var optionalsExpected = `{
"sr": "",
"omitempty": 0,