各种结构相互转换
map转结构体的函数
封装的函数
// 实现map转结构体的函数 func Map2Struct(source map[string]interface{}, target interface{}) { if err := mapstructure.Decode(source, target); err != nil { } Map2StructTaged(source, target, "json") } func Map2StructTaged(source map[string]interface{}, target interface{}, tag string) { cfg := &mapstructure.DecoderConfig{ Metadata: nil, Result: target, TagName: tag, } decoder, _ := mapstructure.NewDecoder(cfg) if err := decoder.Decode(source); err != nil { } }
使用原生方法进行的测试
package main import ( "fmt" "github.com/goinggo/mapstructure" ) type Person struct { Name string Age int } func MapToStruct() (p Person){ mapInstance := make(map[string]interface{}) mapInstance["Name"] = "liang637210" mapInstance["Age"] = 28 var person Person //将 map 转换为指定的结构体 if err := mapstructure.Decode(mapInstance, &person); err != nil { fmt.Println(err) } fmt.Printf("map2struct后得到的 struct 内容为:%v,类型为:%T \n", person,person) return person } func main(){ ret := MapToStruct() fmt.Printf("ret>>> %v, %T",ret, ret) }
其他
package parsexx import ( "database/sql" "encoding/json" "errors" "fmt" "log" "reflect" "strings" "10.0.2.35/bicloud/optimus/src/utils/mathtool" "github.com/chenhg5/collection" "github.com/goinggo/mapstructure" ) // Json2Any 字符串转一切,需传入指针 func Json2Any(infoByte []byte, target interface{}) error { if err := json.Unmarshal(infoByte, target); err != nil { return errors.New(fmt.Sprintf("%v", err)) } return nil } func Json2List(infoByte []byte, target *[]interface{}) error { if err := json.Unmarshal(infoByte, target); err != nil { return errors.New(fmt.Sprintf("%v", err)) } return nil } func struct2Map(obj interface{}, protoAdapt bool) map[string]interface{} { t := reflect.TypeOf(obj) v := reflect.ValueOf(obj) var data = make(map[string]interface{}) for i := 0; i < t.NumField(); i++ { // 处理proto struct:首字母小写、XXX_字段删除 keyName := t.Field(i).Name if protoAdapt { if strings.HasPrefix(keyName, "XXX_") { continue } keyName = mathtool.StrFirstToLow(keyName) } data[keyName] = v.Field(i).Interface() } return data } func Struct2Map(source interface{}) map[string]interface{} { return struct2Map(source, true) } func Map2Struct(source map[string]interface{}, target interface{}) { if err := mapstructure.Decode(source, target); err != nil { } // Map2StructTaged(source, target, "json") } func Map2StructTaged(source map[string]interface{}, target interface{}, tag string) { cfg := &mapstructure.DecoderConfig{ Metadata: nil, Result: target, TagName: tag, } decoder, _ := mapstructure.NewDecoder(cfg) if err := decoder.Decode(source); err != nil { } } func ToSqlNullHookFunc(f reflect.Kind, t reflect.Kind, data interface{}) (interface{}, error) { switch f { case reflect.String: var s sql.NullString if t == reflect.Struct { s = sql.NullString{ String: data.(string), Valid: true, } return s, nil } case reflect.Int32: var s sql.NullInt32 if t == reflect.Struct { s = sql.NullInt32{ Int32: data.(int32), Valid: true, } return s, nil } case reflect.Int64: var s sql.NullInt64 if t == reflect.Struct { s = sql.NullInt64{ Int64: data.(int64), Valid: true, } return s, nil } default: return data, nil } return data, nil } func Map2SqlTaged(source map[string]interface{}, target interface{}, tag string) { cfg := &mapstructure.DecoderConfig{ Metadata: nil, DecodeHook: ToSqlNullHookFunc, // 处理sql structure Result: target, TagName: tag, } decoder, _ := mapstructure.NewDecoder(cfg) if err := decoder.Decode(source); err != nil { } } func Map2Json(source map[string]interface{}) []byte { target, err := json.Marshal(source) if err != nil { } return target } func Json2Map(source []byte, target *map[string]interface{}) { if err := json.Unmarshal([]byte(source), target); err != nil { } } func Struct2Json(source interface{}) []byte { target, err := json.Marshal(source) if err != nil { } return target } func Json2Struct(source []byte, target interface{}) { err := json.Unmarshal([]byte(source), target) if err != nil { } } // StructByDelField 删除某些字段后返回新的struct func StructByDelField(obj interface{}, fields []string, target interface{}) { t := reflect.TypeOf(obj) v := reflect.ValueOf(obj) var data = make(map[string]interface{}) for i := 0; i < t.NumField(); i++ { keyName := t.Field(i).Name if collection.Collect(fields).Contains(keyName) { continue } data[keyName] = v.Field(i).Interface() } Map2Struct(data, target) } // GetFieldName 获取结构体中字段的名称 func GetFieldName(structName interface{}) []string { // t := reflect.TypeOf(structName) // if t.Kind() == reflect.Ptr { // t = t.Elem() // } // if t.Kind() != reflect.Struct { // return nil // } // fieldNum := t.NumField() // result := make([]string, 0, fieldNum) // for i := 0; i < fieldNum; i++ { // result = append(result, t.Field(i).Name) // } // return result return GetFieldNameTaged(structName, "") } // GetFieldNameTaged 获取结构体tag名字 func GetFieldNameTaged(structName interface{}, tag string) []string { t := reflect.TypeOf(structName) if t.Kind() == reflect.Ptr { t = t.Elem() } if t.Kind() != reflect.Struct { log.Println("Check type error not Struct") return nil } fieldNum := t.NumField() result := make([]string, 0, fieldNum) for i := 0; i < fieldNum; i++ { if tag != "" { name := t.Field(i).Tag.Get(tag) result = append(result, name) } else { result = append(result, t.Field(i).Name) } } return result }
~~~