企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
### **第一题:** 使用反射来遍历结构体的字段,调用结构体的方法,并获取结构体标签的值 ![](https://img.kancloud.cn/ca/4a/ca4ac7901a4af8dfdfeb81c0347e5f51_1209x2057.png) ``` package main import( "fmt" "reflect" ) type Student struct { Name string `json:"name"` Age int `json:"age"` Sex string `json:"sex"` Skill string `json:"skill"` Score float64 `json:"score"` } func (stu Student) Print(){ fmt.Printf("stu value is %v\n",stu) } func (stu Student) GetSum(n,y int) int { res := n + y return res } func (stu Student)Set(Name,Sex,Skill string,Age int,Score float64){ stu.Name = Name stu.Age = Age stu.Skill = Skill stu.Sex = Sex stu.Score = Score } func TestStruct(a interface{}){ // 获取a的Type aType := reflect.TypeOf(a) // 获取a的value avalue := reflect.ValueOf(a) // 获取avalue的类别 aKind := avalue.Kind() if aKind != reflect.Struct{ fmt.Println("expext struct") return } // 获取结构体有几个字段 stunum := avalue.NumField() // 返回v持有结构体类型值的字段数,如果v的Kind不是Struct会panic fmt.Printf("Student field number is %d",stunum) // 遍历结构体所有字段 for i := 0;i < stunum;i++{ // 获取到struct标签,注意需要通过reflect.Type来获取tag标签的值 tagval := aType.Field(i).Tag.Get("json") // 判断字段有tag就显示,没有就不显示 if tagval != ""{ fmt.Printf("tag How many %d tag = %v\n",i,tagval) } } // 获取到改结构体有多少方法 mehtodall := avalue.NumMethod() // 返回v持有值的方法集的方法数目 fmt.Printf("avalue method by %d\n",mehtodall) /** var params []refkect.Value 方法排序是默认按照,函数名排序(ASCII)码 返回v持有值类型的第i个方法的已绑定(到v的持有值的)状态的函数形式的Value封装 返回值调用Call方法时不应包含接受者;返回持有值的函数总是使用v的持有者作为接受者(即第一个参数) 如果i出界,或者v的持有者是接口类型的零值(nil),会包panic **/ avalue.Method(1).Call(nil) // Call方法使用输入的参数in调用v的持有函数 // 声明了,reflect.Value var params []reflect.Value params = append(params,reflect.ValueOf(10)) params = append(params,reflect.ValueOf(20)) res := avalue.Method(0).Call(params) // 传入的参数是[]reflect.Value,返回[]reflect.Value fmt.Println("res = ",res[0].Int()) } func main(){ per := Student{ Name: "风清扬", Age: 70, Sex: "男", Skill: "独孤九剑", Score: 98.9988, } TestStruct(per) } ``` <br> <br> **运行结果** ``` Student field number is 5tag How many 0 tag = name tag How many 1 tag = age tag How many 2 tag = sex tag How many 3 tag = skill tag How many 4 tag = score avalue method by 3 stu value is {风清扬 70 男 独孤九剑 98.9988} res = 30 ``` <br> **如上代码说明:** (一)34行Kind:Kind返回v持有的值的分类,如果v是Value零值,返回值为Invalid ![](https://img.kancloud.cn/65/35/65352b5d6840d07ed592b06e7e059359_846x129.png) <br> <br> (二)41行NumField:就是将结构体的字段数量返回,reflect.value下的方法 ![](https://img.kancloud.cn/9a/03/9a035f6261f868656d96cd5ddac34f88_904x135.png) <br> <br> (三)48行Field:就是将将结构体的第n个字段返回 ![](https://img.kancloud.cn/14/59/1459bfa63f770c6148d38e3399d58b70_860x135.png) <br> <br> (四)48行Field:改Field是Type的Field,也就是标签, ![](https://img.kancloud.cn/71/0e/710e319cf1ea5b65d42c2590c964987c_922x328.png) <br> <br> (五)56行NumMethod:会统计Student这个结构体中有多少个方法 ![](https://img.kancloud.cn/59/a6/59a653e6499749fabbab260b1a8c3264_832x128.png) <br> <br> (六)68行Method:改方法在value函数封装,所以,Method要传入结构体绑定的第几个方法进行调用,调用形式,也就是传入1,底层会按照方法名,进行ASCII进行顺序调用 返回v持有值类型的第i个方法的已绑定(到v的持有值的)状态的函数形式的Value封装 ![](https://img.kancloud.cn/ab/fc/abfc6255989437180c9ef35831fffdcf_869x169.png) <br> <br> (七)62行Call:如果method调用的方法,不需要传参则Call(nil)即可 ![](https://img.kancloud.cn/e2/74/e274b5bc83280b6f5d34fe6d17e56595_841x192.png) <br> <br> ### **第二题:** 1)使用反射的方式来获取结构体的tag标签,遍历字段的值,修改字段值,调用结构体方法(要求:通过传递地址的方式完成在前面案例上修改即可)