package sort import ( "github.com/IceWhaleTech/CasaOS/model" "sort" ) // 数据集类型, 与上一篇排序文章(多字段单独排序)比较, less字段的数据类型不再是 func(p1, p2 *Change) bool // 而是 []func(p1, p2 *Change) bool 因为在第一个比较的值相等的情况下, 还要比较第二个值, 所以这里需要多个比较函数 type volSorter struct { vol []model.Volume less []lessFuncVol } // sort接口方法之一(Less) type lessFuncVol func(p1, p2 *model.Volume) bool // Sort 函数有两个作用 // 第一, 将参数(实际的数据集)赋值给ms对象 // 第二, 调用内置sort函数进行排序操作 func (ms *volSorter) Sort(vol []model.Volume) { ms.vol = vol sort.Sort(ms) } // OrderedBy 函数的作用是返回一个multiSorter实例, 并将所有的实际排序函数赋值给实例的less字段, // 上面已经为multiSorter结构体定义了Sort方法, 所以该函数的返回值可以直接调用Sort方法进行排序 // 该函数中, 为multiSorter结构体中的less字段赋值, Sort方法中又将实际数据集传入, 赋值给multiSorter的ports字段 // 一个函数, 一个方法调用过后, multiSorter实例中两个字段就已经全部被正确赋值, 可以调用系统sort函数进行排序 // 该函数也可看作是一个工厂方法, 用来生成less字段已经被赋值的multiSorter实例 func VolSort(less ...lessFuncVol) *volSorter { return &volSorter{ less: less, } } // Len 为sort接口方法之一 func (ms *volSorter) Len() int { return len(ms.vol) } // Swap 为sort接口方法之一 func (ms *volSorter) Swap(i, j int) { ms.vol[i], ms.vol[j] = ms.vol[j], ms.vol[i] } // Less 为sort接口方法之一 func (ms *volSorter) Less(i, j int) bool { temp := ms.vol p, q := &temp[i], &temp[j] // Try all but the last comparison. var k int // 由于可能有多个需要排序的字段, 也就对应了多个less函数, 当第一个字段的值相等时, // 需要依次尝试比对后续其他字段的值得大小, 所以这里需要获取比较函数的长度, 以便遍历比较 for k = 0; k < len(ms.less)-1; k++ { // 提取比较函数, 将函数赋值到新的变量中以便调用 less := ms.less[k] switch { case less(p, q): // 如果 p < q, 返回值为true, 不存在两个值相等需要比较后续字段的情况, 所以这里直接返回 // 如果 p > q, 返回值为false, 则调到下一个case中处理 return true case less(q, p): // 如果 p > q, 返回值为false, 不存在两个值相等需要比较后续字段的情况, 所以这里直接返回 return false } // 如果代码走到这里, 说明ms.less[k]函数比较后 p == q; 重新开始下一次循环, 更换到下一个比较函数处理 continue } // 如果代码走到这里, 说明所有的比较函数执行过后, 所有比较的值都相等 // 直接返回最后一次的比较结果数据即可 return ms.less[k](p, q) }