这个资料真的难找,搜了一圈,基本都是一样的,都是讲怎么通过反射改变slice中的值,关于自定义字段排序的资料缺是一个也没有。

这也难怪,如果不是为了重构一个方法,关于排序复用代码太多,我也不会查找这方面的资料,并通过实践测试,找到了相关的方法。

sort.Slicerelfect.ValueOf
// Slice sorts the provided slice given the provided less function.
//
// The sort is not guaranteed to be stable. For a stable sort, use
// SliceStable.
//
// The function panics if the provided interface is not a slice.
func Slice(slice interface{}, less func(i, j int) bool) {
	rv := reflectValueOf(slice)
	swap := reflectSwapper(slice)
	length := rv.Len()
	quickSort_func(lessSwap{less, swap}, 0, length, maxDepth(length))
}
reflect.Valueof.Index

代码:

type Str struct {
	A string
	V int
}

func TestBindParams(t *testing.T) {
	var tt = []Str{{A: "test A", V: 2}, {A: "test b", V: 1}, {A: "test c", V: -1}}
	f := "V"
	sort.Slice(tt, func(i, j int) bool {
		tmp := reflect.ValueOf(tt)
        // 指针与结构体获取反射字段值的用法不一样
		if tmp.Type().Elem().Kind() == reflect.Ptr {
			return tmp.Index(i).Elem().FieldByName(f).Int() < tmp.Index(j).Elem().FieldByName(f).Int()
		}
		return tmp.Index(i).FieldByName(f).Int() < tmp.Index(j).FieldByName(f).Int()
	})
	t.Log(tt)
}

输出:

=== RUN   TestBindParams
    TestBindParams: http_test.go:153: [{test c -1} {test b 1} {test A 2}]
--- PASS: TestBindParams (0.00s)
PASS

Process finished with exit code 0