在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}