当前位置:   article > 正文

go的反射和断言

go的反射和断言

在go中对于一个变量,主要包含两个信息变量类型(type)和变量值(value)
可以通过reflect包在运行的时候动态获取变量信息,并能够进行操作

对于Type可以通过reflect.TypeOf()获取到变量的类型信息

reflect.TypeOf()返回的是一个Type类型,里面保存了类型的信息

通过reflect.ValueOf()来获取到变量的值部分

reflect.ValueOf()返回的是一个Value类型

可以通过Value.Kind()获取到该变量大概的类型

go中的断言可以将一个未知的类型转换为指定的类型

通过结合反射和断言,我们可以实现这样的一个功能

  1. // UpdateFieldMap 获取更新字段键值对,除了在empty记录的字段整数类型为0或者string类型为空默认不更新
  2. func UpdateFieldMap(in any, empty map[string]struct{}) map[string]any {
  3. out := make(map[string]any)
  4. if empty == nil {
  5. empty = make(map[string]struct{})
  6. }
  7. v := reflect.ValueOf(in)
  8. if v.Kind() == reflect.Ptr {
  9. v = v.Elem()
  10. }
  11. if v.Kind() != reflect.Struct {
  12. panic(fmt.Errorf("ToMap only accepts structs; got %T", v))
  13. }
  14. typ := v.Type()
  15. for i := 0; i < v.NumField(); i++ {
  16. // 获取字段的值
  17. fieldValue := v.Field(i)
  18. // 获取字段的类型
  19. //fieldType := fieldValue.Type()
  20. columns := strings.Split(typ.Field(i).Tag.Get("gorm"), ";")
  21. column := ""
  22. for _, s := range columns {
  23. if strings.HasPrefix(s, "column:") {
  24. column = s[7:]
  25. }
  26. }
  27. switch fieldValue.Kind() {
  28. case reflect.Int:
  29. //fmt.Println(column, fieldValue.Interface().(int))
  30. val := fieldValue.Interface().(int)
  31. _, ok := empty[column]
  32. if val != 0 || ok {
  33. out[column] = val
  34. }
  35. case reflect.String:
  36. val := fieldValue.Interface().(string)
  37. _, ok := empty[column]
  38. if val != "" || ok {
  39. out[column] = val
  40. }
  41. case reflect.Struct:
  42. if fieldValue.Type() == reflect.TypeOf(time.Time{}) {
  43. // 处理 time.Time 类型
  44. val := fieldValue.Interface().(time.Time)
  45. _, ok := empty[column]
  46. if !val.IsZero() || ok {
  47. out[column] = val
  48. }
  49. }
  50. }
  51. }
  52. return out
  53. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/675916
推荐阅读
相关标签
  

闽ICP备14008679号