+
+// SortSlice sorts a slice of structs based on a field name and order.
+// It now supports basic types, time.Time, and pointers to basic types.
+// slicePtr: A pointer to the slice of structs to be sorted.
+// fieldName: The name of the struct field to sort by (must be exported).
+// ascending: true for ascending order, false for descending order.
+func SortSlice(slicePtr any, fieldName string, ascending bool) error {
+ // 1. 使用反射获取切片的值
+ sliceVal := reflect.ValueOf(slicePtr)
+ if sliceVal.Kind() != reflect.Ptr {
+ return fmt.Errorf("must provide a pointer to a slice")
+ }
+ sliceVal = sliceVal.Elem()
+ if sliceVal.Kind() != reflect.Slice {
+ return fmt.Errorf("must provide a pointer to a slice")
+ }
+
+ // 2. 检查切片是否为空
+ if sliceVal.Len() == 0 {
+ return nil // 空切片无需排序
+ }
+
+ // 3. 验证字段是否存在
+ firstElem := sliceVal.Index(0)
+ if firstElem.Kind() != reflect.Struct {
+ return fmt.Errorf("slice elements must be structs")
+ }
+ field := firstElem.FieldByName(fieldName)
+ if !field.IsValid() {
+ return fmt.Errorf("field '%s' not found in struct", fieldName)
+ }
+
+ // 4. 使用 sort.Slice 进行排序
+ sort.Slice(sliceVal.Interface(), func(i, j int) bool {
+ // 获取第 i 个和第 j 个元素的指定字段
+ fieldI := sliceVal.Index(i).FieldByName(fieldName)
+ fieldJ := sliceVal.Index(j).FieldByName(fieldName)
+
+ // 比较函数
+ isLess := func() bool {
+ // --- 处理指针类型 ---
+ if fieldI.Kind() == reflect.Ptr {
+ // 规则1: 处理 nil 值
+ isNilI := fieldI.IsNil()
+ isNilJ := fieldJ.IsNil()
+
+ if isNilI && isNilJ {
+ return false // 两个都为 nil,视为相等,不交换
+ }
+ if isNilI { // i 是 nil, j 不是
+ return true // nil 值排在前面 (升序)
+ }
+ if isNilJ { // j 是 nil, i 不是
+ return false
+ }
+
+ // 规则2: 两个指针都不为 nil,解引用后比较
+ elemI := fieldI.Elem()
+ elemJ := fieldJ.Elem()
+ // 现在 elemI 和 elemJ 是指针指向的实际值,继续下面的 switch 逻辑
+ return compareValues(elemI, elemJ)
+ }
+
+ // --- 处理非指针类型 ---
+ return compareValues(fieldI, fieldJ)
+ }()
+
+ // 根据排序方向返回结果
+ if ascending {
+ return isLess
+ }
+ return !isLess
+ })
+
+ return nil
+}
+
+// compareValues is a helper function to compare two reflect.Value.
+// It assumes the values are of the same comparable kind.
+func compareValues(valI, valJ reflect.Value) bool {
+ switch valI.Kind() {
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ return valI.Int() < valJ.Int()
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+ return valI.Uint() < valJ.Uint()
+ case reflect.Float32, reflect.Float64:
+ return valI.Float() < valJ.Float()
+ case reflect.String:
+ return strings.Compare(valI.String(), valJ.String()) < 0
+ case reflect.Struct:
+ // 特别处理 time.Time 类型
+ if t, ok := valI.Interface().(time.Time); ok {
+ return t.Before(valJ.Interface().(time.Time))
+ }
+ // 其他结构体不支持比较
+ return false
+ default:
+ // 对于不支持的类型,默认不交换顺序
+ return false
+ }
+}