package structx import ( "encoding/json" "fmt" "reflect" "strings" ) // 工具函数 func getJSONTagName(field reflect.StructField) string { jsonTag := field.Tag.Get("json") if jsonTag == "" || jsonTag == "-" { return field.Name } return strings.Split(jsonTag, ",")[0] } // 是否实现了json.Unmarshaler接口 func hasUnmarshalJSON(t reflect.Type) bool { if t.Kind() == reflect.Ptr { t = t.Elem() } unmarshalerType := reflect.TypeOf((*json.Unmarshaler)(nil)).Elem() return t.Implements(unmarshalerType) || reflect.PointerTo(t).Implements(unmarshalerType) } // 是否实现了text.Unmarshaler接口 func hasUnmarshalText(t reflect.Type) bool { if t.Kind() == reflect.Ptr { t = t.Elem() } textUnmarshalerType := reflect.TypeOf((*interface { UnmarshalText([]byte) error })(nil)).Elem() return t.Implements(textUnmarshalerType) || reflect.PointerTo(t).Implements(textUnmarshalerType) } // 设置json.Unmarshaler接口的值 func setUnmarshalJSONValue(field reflect.Value, value interface{}) error { jsonBytes, err := json.Marshal(value) if err != nil { return err } var fieldAddr reflect.Value if field.CanAddr() { fieldAddr = field.Addr() } else { temp := reflect.New(field.Type()) temp.Elem().Set(field) fieldAddr = temp } if unmarshaler, ok := fieldAddr.Interface().(json.Unmarshaler); ok { return unmarshaler.UnmarshalJSON(jsonBytes) } return fmt.Errorf("类型未实现Unmarshaler") } // 设置text.Unmarshaler接口的值 func setUnmarshalTextValue(field reflect.Value, value string) error { var fieldAddr reflect.Value if field.CanAddr() { fieldAddr = field.Addr() } else { temp := reflect.New(field.Type()) temp.Elem().Set(field) fieldAddr = temp } if unmarshaler, ok := fieldAddr.Interface().(interface { UnmarshalText([]byte) error }); ok { return unmarshaler.UnmarshalText([]byte(value)) } return fmt.Errorf("类型未实现UnmarshalText") } // 是否是基础结构体类型 func isBasicStructType(t reflect.Type) bool { if t.Kind() == reflect.Ptr { t = t.Elem() } return basicStructTypes[t.String()] } // 设置基础结构体类型的值 func setBasicStructValue(field reflect.Value, value string) error { if hasUnmarshalText(field.Type()) { return setUnmarshalTextValue(field, value) } return json.Unmarshal([]byte(value), field.Addr().Interface()) } // 设置指针类型的值 func setPointerFieldValue(field reflect.Value, value string) (interface{}, error) { if field.Kind() != reflect.Ptr { return nil, fmt.Errorf("期望指针类型") } if field.IsNil() { field.Set(reflect.New(field.Type().Elem())) } return new(defaultValueSetter).SetFieldValue(field.Elem(), value) } // 是否是类型别名 func isTypeAlias(t reflect.Type) bool { if t.Kind() == reflect.Ptr { t = t.Elem() } return t.PkgPath() != "" && basicKinds[t.Kind()] } // 设置类型别名的值 func setTypeAliasValue(field reflect.Value, value string) (interface{}, error) { baseType := getBaseTypeFromAlias(field.Type()) if baseType == nil { return nil, fmt.Errorf("无法获取基础类型") } converter, exists := typeConverters[baseType.Kind()] if !exists { return nil, fmt.Errorf("不支持的基础类型") } baseValue := reflect.New(baseType).Elem() result, err := converter(baseValue, value) if err != nil { return nil, err } convertedValue, err := convertToTypeAlias(field.Type(), result) if err != nil { return nil, err } field.Set(reflect.ValueOf(convertedValue)) return convertedValue, nil } // 是否是自定义结构体类型 func isCustomStructType(t reflect.Type) bool { if t.Kind() == reflect.Ptr { t = t.Elem() } return t.PkgPath() != "" && !isBasicStructType(t) && !isTypeAlias(t) && t.Kind() == reflect.Struct } // 设置自定义结构体类型的值 func setCustomTypeValue(field reflect.Value, value string) (interface{}, error) { if hasUnmarshalText(field.Type()) { if err := setUnmarshalTextValue(field, value); err != nil { return nil, err } return field.Interface(), nil } var jsonData interface{} if err := json.Unmarshal([]byte(value), &jsonData); err != nil { return nil, err } jsonBytes, err := json.Marshal(jsonData) if err != nil { return nil, err } if err := json.Unmarshal(jsonBytes, field.Addr().Interface()); err != nil { return nil, err } return field.Interface(), nil } // 设置基础结构体元素的值 func setBasicStructElement(elemValue reflect.Value, item interface{}) error { return setStructElement(elemValue, item) } // 设置结构体元素的值 func setStructElement(elemValue reflect.Value, item interface{}) error { jsonBytes, err := json.Marshal(item) if err != nil { return err } return json.Unmarshal(jsonBytes, elemValue.Addr().Interface()) }