赞
踩
在go中对于一个变量,主要包含两个信息变量类型(type)和变量值(value)
可以通过reflect包在运行的时候动态获取变量信息,并能够进行操作
对于Type可以通过reflect.TypeOf()获取到变量的类型信息
reflect.TypeOf()返回的是一个Type类型,里面保存了类型的信息
通过reflect.ValueOf()来获取到变量的值部分
reflect.ValueOf()返回的是一个Value类型
可以通过Value.Kind()获取到该变量大概的类型
go中的断言可以将一个未知的类型转换为指定的类型
通过结合反射和断言,我们可以实现这样的一个功能
- // UpdateFieldMap 获取更新字段键值对,除了在empty记录的字段整数类型为0或者string类型为空默认不更新
- func UpdateFieldMap(in any, empty map[string]struct{}) map[string]any {
- out := make(map[string]any)
- if empty == nil {
- empty = make(map[string]struct{})
- }
-
- v := reflect.ValueOf(in)
- if v.Kind() == reflect.Ptr {
- v = v.Elem()
- }
- if v.Kind() != reflect.Struct {
- panic(fmt.Errorf("ToMap only accepts structs; got %T", v))
- }
-
- typ := v.Type()
- for i := 0; i < v.NumField(); i++ {
-
- // 获取字段的值
- fieldValue := v.Field(i)
- // 获取字段的类型
- //fieldType := fieldValue.Type()
-
- columns := strings.Split(typ.Field(i).Tag.Get("gorm"), ";")
- column := ""
- for _, s := range columns {
- if strings.HasPrefix(s, "column:") {
- column = s[7:]
- }
- }
- switch fieldValue.Kind() {
- case reflect.Int:
- //fmt.Println(column, fieldValue.Interface().(int))
- val := fieldValue.Interface().(int)
-
- _, ok := empty[column]
- if val != 0 || ok {
- out[column] = val
- }
- case reflect.String:
- val := fieldValue.Interface().(string)
-
- _, ok := empty[column]
- if val != "" || ok {
- out[column] = val
- }
- case reflect.Struct:
- if fieldValue.Type() == reflect.TypeOf(time.Time{}) {
- // 处理 time.Time 类型
- val := fieldValue.Interface().(time.Time)
- _, ok := empty[column]
- if !val.IsZero() || ok {
- out[column] = val
- }
- }
- }
- }
-
- return out
-
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。