go icon indicating copy to clipboard operation
go copied to clipboard

UnmarshalJSON bug

Open lay-225 opened this issue 4 years ago • 1 comments

UnmarshalJSON 无法反序列化自定义类型

func TestSetForm(t *testing.T) {
	val := `{"id":"mQgb9MXL","lv":1,"itemId":111,"inFms":[1]}`
	t.Log("val", val)
	type Soldier struct {
		Id     string     //唯一id
		Lv     int        //等级
		ItemId int        //物品表的id
		InFms  slices.Set //在那几个阵型中
	}
	so := Soldier{}

	err:=jsoniter.Unmarshal([]byte(val), &so)

	t.Log(so,err)

}

type Set map[interface{}]struct{}

func SetForm(slice interface{}) Set {
	if slice == nil {
		return Set{}
	}
	rfValue := reflect.ValueOf(slice)
	if rfValue.Kind() != reflect.Slice && rfValue.Kind() != reflect.Array {
		return Set{}
	}
	set := make(Set, rfValue.Len())
	for i := 0; i < rfValue.Len(); i++ {
		set[rfValue.Index(i).Interface()] = struct{}{}
	}
	return set
}

func (s Set) Fill(slice interface{}) {
	rfValue := reflect.ValueOf(slice)
	if rfValue.Kind() != reflect.Slice && rfValue.Kind() != reflect.Array {
		return
	}
	for i := 0; i < rfValue.Len(); i++ {
		s[rfValue.Index(i).Interface()] = struct{}{}
	}
}
func (s Set) Add(item interface{}) bool {
	oldLen := s.Len()
	s[item] = struct{}{}
	return s.Len() > oldLen
}
func (s Set) Delete(item interface{}) {
	delete(s, item)
}
func (s Set) Members() []interface{} {
	ret := make([]interface{}, 0, len(s))
	for i := range s {
		ret = append(ret, i)
	}
	return ret
}
func (s Set) Len() int {
	return len(s)
}
func (s Set) IsMembers(m interface{}) bool {
	_, ok := s[m]
	return ok
}

func (s *Set) UnmarshalJSON(text []byte) error {
	if len(text) == 0 {
		return nil
	}
	var i interface{}
	err := jsoniter.Unmarshal(text, &i)
	if err != nil {
		return nil
	}
	*s = SetForm(i)
	return nil
}

func (s *Set) MarshalJSON() (text []byte, err error) {
	return jsoniter.Marshal(s.Members())
}

最终 无法反序列化inFms字段。 换成标准库后反序列化成功

lay-225 avatar Apr 22 '21 09:04 lay-225

不维护了吗。。。

lay-225 avatar Apr 26 '21 06:04 lay-225