1 Star 0 Fork 0

gomod / utils

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
structure.go 3.67 KB
一键复制 编辑 原始数据 按行查看 历史
Damin 提交于 2022-07-08 20:59 . copy
package structure
import (
"errors"
"fmt"
"github.com/goinggo/mapstructure"
"github.com/jinzhu/copier"
"reflect"
"strconv"
"strings"
)
// MergeValue 将source数据覆盖target中的空数据(默认值认为是空)
func MergeValue(source, target interface{}) error {
sType, tType := reflect.TypeOf(source), reflect.TypeOf(target)
if !reflect.DeepEqual(sType, tType) {
return errors.New("cannot merge structs of different structure types")
}
srcVal := reflect.ValueOf(source)
if !srcVal.CanSet() && !(srcVal.Kind() == reflect.Ptr) {
return errors.New(fmt.Sprintf("can't set %v", reflect.TypeOf(source).Kind()))
}
opt := copier.Option{
IgnoreEmpty: true,
DeepCopy: true,
}
copier.CopyWithOption(target, source, opt)
return nil
}
func isBlank(value reflect.Value) bool {
switch value.Kind() {
case reflect.String:
return value.Len() == 0
//case reflect.Bool:
// return !value.Bool()
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return value.Int() == 0
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
return value.Uint() == 0
case reflect.Float32, reflect.Float64:
return value.Float() == 0
//case reflect.Interface, reflect.Ptr:
// return value.IsNil()
}
return false
}
// StructToMap 结构体转map
func StructToMap(obj interface{}) map[string]interface{} {
out := make(map[string]interface{})
t := reflect.TypeOf(obj)
v := reflect.ValueOf(obj)
// 取出指针的值
if v.Kind() == reflect.Ptr {
v = v.Elem()
}
// 判断是否是结构体
if v.Kind() != reflect.Struct {
fmt.Println("it is not struct")
return nil
}
for i := 0; i < t.NumField(); i++ {
out[t.Field(i).Name] = v.Field(i).Interface()
}
return out
}
// MapToStruct map转为struct,名称、类型一致
func MapToStruct(m interface{}, structure interface{}) error {
return mapstructure.Decode(m, structure)
}
// ConvertToStruct 从map中复制数据到结构体,按名称
func ConvertToStruct(Map interface{}, pointer interface{}) {
// reflect.Ptr类型 *main.Person
pointertype := reflect.TypeOf(pointer)
// reflect.Value类型
pointervalue := reflect.ValueOf(pointer)
// struct类型 main.Person
structType := pointertype.Elem()
// 将interface{}类型的map转换为 map[string]interface{}
m := Map.(map[string]interface{})
// 遍历结构体字段
for i := 0; i < structType.NumField(); i++ {
// 获取指定字段的反射值
f := pointervalue.Elem().Field(i)
//获取struct的指定字段
stf := structType.Field(i)
// 获取tag
name := strings.Split(stf.Tag.Get("json"), ",")[0]
// 判断是否为忽略字段
if name == "-" {
continue
}
// 判断是否为空,若为空则使用字段本身的名称获取value值
if name == "" {
name = stf.Name
}
//获取value值
v, ok := m[name]
if !ok {
continue
}
//获取指定字段的类型
kind := pointervalue.Elem().Field(i).Kind()
// 若字段为指针类型
if kind == reflect.Ptr {
// 获取对应字段的kind
kind = f.Type().Elem().Kind()
}
// 设置对应字段的值
switch kind {
case reflect.Int:
res, err := strconv.ParseInt(fmt.Sprint(v), 10, 64)
if err == nil {
pointervalue.Elem().Field(i).SetInt(res)
}
case reflect.Uint:
res, err := strconv.ParseUint(fmt.Sprint(v), 10, 64)
if err == nil {
pointervalue.Elem().Field(i).SetUint(res)
}
case reflect.Bool:
res, err := strconv.ParseBool(fmt.Sprint(v))
if err == nil {
pointervalue.Elem().Field(i).SetBool(res)
}
case reflect.String:
pointervalue.Elem().Field(i).SetString(fmt.Sprint(v))
}
}
}
// Copy 结构体映射
func Copy(s, ts interface{}) error {
return copier.Copy(ts, s)
}
Go
1
https://gitee.com/gomod/utils.git
git@gitee.com:gomod/utils.git
gomod
utils
utils
b13fe042f36b

搜索帮助