Loading...

【Golang实战】反射设置结构体字段值

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