这个测试用例,是在上一篇通过反射自定义排序字段的基础上做的补充,因为在业务代码中涉及到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