package main
import (
"encoding"
"fmt"
"reflect"
"strconv"
)
type reflectWithString struct {
k reflect.Value
v reflect.Value
ks string
}
func main() {
m := map[string]interface{}{"1": 1}
v := reflect.ValueOf(m)
sv := make([]reflectWithString, v.Len())
m["2"] = 2
mi := v.MapRange()
for i := 0; mi.Next(); i++ {
sv[i].k = mi.Key()
sv[i].v = mi.Value()
if err := sv[i].resolve(); err != nil {
fmt.Errorf("json: encoding error for type %q: %q", v.Type().String(), err.Error())
}
}
}
func (w *reflectWithString) resolve() error {
if w.k.Kind() == reflect.String {
w.ks = w.k.String()
return nil
}
if tm, ok := w.k.Interface().(encoding.TextMarshaler); ok {
if w.k.Kind() == reflect.Pointer && w.k.IsNil() {
return nil
}
buf, err := tm.MarshalText()
w.ks = string(buf)
return err
}
switch w.k.Kind() {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
w.ks = strconv.FormatInt(w.k.Int(), 10)
return nil
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
w.ks = strconv.FormatUint(w.k.Uint(), 10)
return nil
}
panic("unexpected map key type")
}
在官方包中,通过反射获取先获取了map的len长度得到sv的长度。
如果在v.MapRange() 前,将map的长度扩大,
就会出现sv的下标越界问题触发painc;
如果内容改变,就会出现 序列化 后的数据不是之前的数据,
因此在操作map时,一点要确认 不能并发操作读写。