这个测试用例,是在上一篇通过反射自定义排序字段的基础上做的补充,因为在业务代码中涉及到slice排序完之后,给最小元素的字段赋值场景。
type Str struct {
A string
V int
}
func TestReflectMapSet(t *testing.T) {
var ddd = map[int]*Str{
2: {A: "test A", V: 2},
1: {A: "test b", V: 1},
-1: {A: "test c", V: -1},
}
tmpData := ddd[1]
// tmpData 一定是指针类型的
reflect.ValueOf(tmpData).Elem().FieldByName("V").SetInt(22)
ddd[1] = tmpData
for _, d := range ddd {
t.Log(d)
}
}
输出:
=== RUN TestReflectMapSet
TestReflectMapSet: http_test.go:183: &{test A 2}
TestReflectMapSet: http_test.go:183: &{test b 22}
TestReflectMapSet: http_test.go:183: &{test c -1}
--- PASS: TestReflectMapSet (0.00s)
PASS
以下是结合了通过反射自定义字段排序,以及给指定字段赋值的业务代码
type DividedDecInfo struct {
SkuId uint64
CouponAmount int
}
func TestReflectSort(t *testing.T) {
var data = map[uint64]*DividedDecInfo{
12: {SkuId: 12, CouponAmount: 3},
13: {SkuId: 13, CouponAmount: 4},
34: {SkuId: 34, CouponAmount: 5},
}
sortByType2(data, 13, "CouponAmount")
for _, d := range data {
t.Log(d)
}
}
func sortByType2(data map[uint64]*DividedDecInfo, amount int, amountObj string) {
var (
tmpDdi []*DividedDecInfo
num, tmpAmount int
)
for _, ddi := range data {
tmpDdi = append(tmpDdi, ddi)
}
num = len(tmpDdi)
if num >= 2 {
// 反射排序
sort.Slice(tmpDdi, func(i, j int) bool {
tmp := reflect.ValueOf(tmpDdi)
return tmp.Index(i).Elem().FieldByName(amountObj).Int() > tmp.Index(j).Elem().FieldByName(amountObj).Int()
})
refTmp := reflect.ValueOf(tmpDdi)
for i := 0; i <= num-2; i++ {
log.Println(tmpDdi[i])
// 反射取值
tmpAmount += int(refTmp.Index(i).Elem().FieldByName(amountObj).Int())
}
// 反射赋值
tmpData := data[tmpDdi[num-1].SkuId]
reflect.ValueOf(tmpData).Elem().FieldByName(amountObj).SetInt(int64(amount - tmpAmount))
}
}
输出:
=== RUN TestReflectSort
2021/02/14 22:38:30 &{34 5}
2021/02/14 22:38:30 &{13 4}
TestReflectSort: http_test.go:215: &{12 4}
TestReflectSort: http_test.go:215: &{13 4}
TestReflectSort: http_test.go:215: &{34 5}
--- PASS: TestReflectSort (0.02s)
PASS