Tao Wen 8 лет назад
Родитель
Сommit
ceb8c8a733
3 измененных файлов с 39 добавлено и 19 удалено
  1. 3 1
      feature_reflect.go
  2. 12 9
      feature_reflect_object.go
  3. 24 9
      jsoniter_reflect_struct_test.go

+ 3 - 1
feature_reflect.go

@@ -200,7 +200,9 @@ func (decoder *mapDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
 	mapInterface.word = ptr
 	realInterface := (*interface{})(unsafe.Pointer(&mapInterface))
 	realVal := reflect.ValueOf(*realInterface).Elem()
-
+	if realVal.IsNil() {
+		realVal.Set(reflect.MakeMap(realVal.Type()))
+	}
 	for field := iter.ReadObject(); field != ""; field = iter.ReadObject() {
 		elem := reflect.New(decoder.elemType)
 		decoder.elemDecoder.decode(unsafe.Pointer(elem.Pointer()), iter)

+ 12 - 9
feature_reflect_object.go

@@ -33,14 +33,17 @@ func encoderOfStruct(typ reflect.Type) (Encoder, error) {
 				fieldNames = []string{tagParts[0]}
 			}
 		}
-		encoder, err := encoderOfType(field.Type)
-		if err != nil {
-			return prefix(fmt.Sprintf("{%s}", field.Name)).addToEncoder(encoder, err)
-		}
-		// map is stored as pointer in the struct
-		// but if struct only has one map, it is inlined
-		if field.Type.Kind() == reflect.Map && typ.NumField() > 1 {
-			encoder = &optionalEncoder{field.Type, encoder}
+		var encoder Encoder
+		if len(fieldNames) > 0 {
+			encoder, err := encoderOfType(field.Type)
+			if err != nil {
+				return prefix(fmt.Sprintf("{%s}", field.Name)).addToEncoder(encoder, err)
+			}
+			// map is stored as pointer in the struct
+			// but if struct only has one map, it is inlined
+			if field.Type.Kind() == reflect.Map && typ.NumField() > 1 {
+				encoder = &optionalEncoder{field.Type, encoder}
+			}
 		}
 		for _, fieldName := range fieldNames {
 			if structEncoder_.firstField == nil {
@@ -85,7 +88,7 @@ func decoderOfStruct(typ reflect.Type) (Decoder, error) {
 				fieldNames = []string{tagParts[0]}
 			}
 		}
-		if decoder == nil {
+		if decoder == nil && len(fieldNames) > 0 {
 			var err error
 			decoder, err = decoderOfType(field.Type)
 			if err != nil {

+ 24 - 9
jsoniter_reflect_struct_test.go

@@ -3,6 +3,7 @@ package jsoniter
 import (
 	"testing"
 	"github.com/json-iterator/go/require"
+	"bytes"
 )
 
 func Test_decode_one_field_struct(t *testing.T) {
@@ -88,15 +89,15 @@ func Test_decode_five_fields_struct(t *testing.T) {
 func Test_decode_ten_fields_struct(t *testing.T) {
 	should := require.New(t)
 	type TestObject struct {
-		field1 string
-		field2 string
-		field3 string
-		field4 string
-		field5 string
-		field6 string
-		field7 string
-		field8 string
-		field9 string
+		field1  string
+		field2  string
+		field3  string
+		field4  string
+		field5  string
+		field6  string
+		field7  string
+		field8  string
+		field9  string
 		field10 string
 	}
 	obj := TestObject{}
@@ -144,3 +145,17 @@ func Test_write_val_one_field_struct(t *testing.T) {
 	should.Nil(err)
 	should.Equal(`{"field-1":"hello"}`, str)
 }
+
+func Test_mixed(t *testing.T) {
+	should := require.New(t)
+	type  AA struct {
+		ID      int `json:"id"`
+		Payload map[string]interface{} `json:"payload"`
+		buf     *bytes.Buffer `json:"-"`
+	}
+	aa := AA{}
+	err := UnmarshalFromString(` {"id":1, "payload":{"account":"123","password":"456"}}`, &aa)
+	should.Nil(err)
+	should.Equal(1, aa.ID)
+	should.Equal("123", aa.Payload["account"])
+}