• Golang使用反射


    1.反射获取变量的值

    1. package main
    2. import (
    3. "fmt"
    4. "reflect"
    5. )
    6. func reflectTest01(b interface{}) {
    7. //通过反射获取变量的type,kind,值
    8. //1.获取reflect.Type
    9. rType := reflect.TypeOf(b)
    10. fmt.Println("rType:=", rType)
    11. //2.获取到reflect.Value,int不能直接参与+-*/
    12. rVal := reflect.ValueOf(b)
    13. fmt.Printf("rVal=%v type=%T\n", rVal, rVal)
    14. //3.把reflect.Value能参与基本运算
    15. n1 := 2 + rVal.Int()
    16. fmt.Println("n1=", n1)
    17. //将rVal转成interface{}
    18. iv := rVal.Interface()
    19. //将interface{}通过断言转成需要的类型
    20. num2 := iv.(int)
    21. fmt.Println("num2==", num2)
    22. }
    23. func reflectTest02(b interface{}) {
    24. fmt.Println("===============reflectTest02==================")
    25. rVal := reflect.ValueOf(b)
    26. fmt.Println("rVal:=", rVal)
    27. //将interface{}通过断言转成需要的类型
    28. iv := rVal.Interface()
    29. fmt.Printf("iv=%v iv type=%T\n", iv, iv)
    30. //将interface{}通过断言转为需要的类型
    31. stu, ok := iv.(Student)
    32. if ok {
    33. fmt.Printf("stu.Name=%v stu.Age=%v\n", stu.Name, stu.Age)
    34. }
    35. }
    36. type Student struct {
    37. Name string
    38. Age int
    39. }
    40. func main() {
    41. //1.基本数据类型、interface,reflect.Value进行反射的基本操作
    42. var num int = 100
    43. reflectTest01(num)
    44. //2.定义一个Student的实例
    45. stu := Student{
    46. Name: "Tom",
    47. Age: 200,
    48. }
    49. reflectTest02(stu)
    50. }
    1. =====================reflectTest01==================
    2. rType:= int
    3. rVal=100 type=reflect.Value
    4. n1= 102
    5. num2== 100
    6. ==================reflectTest02==================
    7. rVal:= {Tom 200}
    8. iv={Tom 200} iv type=main.Student
    9. stu.Name=Tom stu.Age=200

    2.使用反射修改变量的值

    1. package main
    2. import (
    3. "fmt"
    4. "reflect"
    5. )
    6. /*
    7. *
    8. 通过反射修改
    9. num int的值
    10. 修改student的值
    11. */
    12. func reflect01(b interface{}) {
    13. //获取value
    14. rVal := reflect.ValueOf(b)
    15. fmt.Printf("rVal kind=%v\n", rVal.Kind())
    16. rVal.Elem().SetInt(20)
    17. }
    18. func main() {
    19. var num int = 100
    20. reflect01(&num)
    21. fmt.Println("num=", num)
    22. }
    1. rVal kind=ptr
    2. num = 20

    3.反射获取结构体的变量和方法

    1. package main
    2. import (
    3. "fmt"
    4. "reflect"
    5. )
    6. type Monster struct {
    7. //添加json标签
    8. Name string `json:"name"`
    9. Age int `json:"monster_age"`
    10. Score float32 `json:"成绩"`
    11. Sex string
    12. }
    13. // 显示结构体的值
    14. func (s Monster) Print() {
    15. fmt.Println("---start---")
    16. fmt.Println(s)
    17. fmt.Println("----end----")
    18. }
    19. // 返回两个数的和
    20. func (s Monster) GetSum(n1, n2 int) int {
    21. return n1 + n2
    22. }
    23. func (s Monster) Set(name string, age int, score float32, sex string) {
    24. s.Name = name
    25. s.Age = age
    26. s.Score = score
    27. s.Sex = sex
    28. }
    29. func TestStruct(a interface{}) {
    30. //获取reflect.Type 类型
    31. tye := reflect.TypeOf(a)
    32. //获取reflect.value类型
    33. val := reflect.ValueOf(a)
    34. //获取a对应的类型
    35. kd := val.Kind()
    36. if kd != reflect.Struct {
    37. fmt.Println("expected struct")
    38. return
    39. }
    40. //获取到该结构体有几个字段
    41. num := val.NumField() //num=4
    42. fmt.Printf("struct has %d fields\n", num)
    43. //遍历结构体的所有字段
    44. for i := 0; i < num; i++ {
    45. fmt.Printf("Field %d: 值为=%v\n", i, val.Field(i))
    46. //获取到struct标签,注意需要通过reflect.Type来获取tag标签的值
    47. tagVal := tye.Field(i).Tag.Get("json")
    48. if tagVal != "" {
    49. fmt.Printf("Field %d: tage为=%v\n", i, tagVal)
    50. }
    51. }
    52. //获取到这结构体有多少方法
    53. numOfMethod := val.NumMethod()
    54. fmt.Printf("struct has %d methods\n", numOfMethod)
    55. //方法的排序默认是按照函数名的排序(ASC||码)
    56. val.Method(1).Call(nil)
    57. //调用结构体的GetSum方法
    58. var params []reflect.Value
    59. params = append(params, reflect.ValueOf(153))
    60. params = append(params, reflect.ValueOf(200))
    61. res := val.Method(0).Call(params) //传入的参数[]reflect.Value,返回的也是[]reflect.Value
    62. fmt.Println("res=", res[0].Int())
    63. }
    64. func main() {
    65. var a Monster = Monster{
    66. Name: "K神",
    67. Age: 500,
    68. Score: 40.5,
    69. }
    70. TestStruct(a)
    71. }
    1. struct has 4 fields
    2. Field 0: 值为=K神
    3. Field 0: tage为=name
    4. Field 1: 值为=500
    5. Field 1: tage为=monster_age
    6. Field 2: 值为=40.5
    7. Field 2: tage为=成绩
    8. Field 3: 值为=
    9. struct has 3 methods
    10. ---start---
    11. {K神 500 40.5 }
    12. ----end----
    13. res= 353

  • 相关阅读:
    【Tableau Server 企业日常问题 24】Tableau server提示工具嵌入工作表,服务器字体乱码问题解决
    一.计算机系统概述
    华为23年9月笔试原题,巨详细题解,附有LeetCode测试链接
    Integrator积分器测试(Simulink仿真)
    联合体union
    Linux账号管理(用户和用户组)
    Flutter:open_file打开本地文件报错问题
    重制版 day 11函数基础
    项目完成 - 基于Django3.x版本 - 开发部署小结
    标准化学校考场自动校时同步时钟系统
  • 原文地址:https://blog.csdn.net/m0_46306264/article/details/132921030