反射的基本使用

一 反射的使用场景——JSON序列化

1 代码

package main

import (
   "encoding/json"
   "fmt"
)

type Monster struct {
   Name string  `json:"monsterName"` // `json:"name"` 就是 struct tag
   Age  int     `json:"monsterAge"`
   Sal  float64 `json:"monsterSal"`
   Sex  string  `json:"monsterSex"`
}

func main() {
   m := Monster{
      Name: "玉兔精",
      Age:  20,
      Sal:  888.76,
      Sex:  "female",
   }


   data, _ := json.Marshal(m)
   fmt.Println("json result", string(data))
}

2 测试

json result {"monsterName":"玉兔精","monsterAge":20,"monsterSal":888.76,"monsterSex":"female"}

3 分析

为什么序列化后,key-val 的 key 值是结构体 Tag 的值,而不是字段的名称。比如,不是 Name,而是 monsterName。这是因为底层使用到了反射。

二 反射的使用场景——函数的适配器和桥连接

1 代码

package main

import "fmt"

func main() {
   // 定义一个匿名函数
   test1 := func(v1 int, v2 int) {
      fmt.Println(v1, v2)
   }
   // 定义另外一个匿名函数
   test2 := func(v1 int, v2 int, s string) {
      fmt.Println(v1, v2, s)
   }

   // 定义一个适配器函数,统一处理接口
   bridge := func(call interface{}, args ...interface{}) {
      fmt.Println("内容")
   }
   // 实现调用 test1 对应的函数
   bridge(test1, 1, 2)
   // 实现调用 test2 对应的函数
   bridge(test2, 1, 2, "求和")
}

2 测试

内容

内容

3 分析

该适配器使用底层使用的便是反射

三 反射的基本介绍

1 基本介绍

a 反射可以在运行时动态获取变量的各种信息, 比如变量的类型(type),类别(kind)。

b 如果是结构体变量,还可以获取到结构体本身的信息:包括结构体的字段、 方法。

c 通过反射,可以修改变量的值,可以调用关联的方法。

d 使用反射,需要 import("reflect")

e 示意图

2 反射的应用场景

a 不知道接口调用哪个函数,根据传入参数在运行时确定调用的具体接口,这种需要对函数和方法反射。例如下面这种桥接模式。

func bridge(funcPtr interface{}, args ...interface{})

第1个参数 funcPtr 以接口的形式传入函数指针,函数参数 args 以可变参数的形式传入,bridge 函数中可以用反射来动态执行 funcPtr 函数。

b 对结构体序列化时,如果结构体有指定 Tag,也会使用到反射生成对应的字符串。

package main

import (
   "encoding/json"
   "fmt"
)

type Monster struct {
   Name string  `json:"monsterName"` // `json:"name"` 就是 struct tag
   Age  int     `json:"monsterAge"`
   Sal  float64 `json:"monsterSal"`
   Sex  string  `json:"monsterSex"`
}

func main() {
   m := Monster{
      Name: "玉兔精",
      Age:  20,
      Sal:  888.76,
      Sex:  "female",
   }


   data, _ := json.Marshal(m)
   fmt.Println("json result", string(data))
}

3 反射重要的函数和概念

a reflect.Type(变量名),获取变量的类型,返回 reflect.Type 类型。

b reflect.ValueOf(变量名),获取变量的值,返回 reflex.Value 类型。reflex.Value 是一个结构体类型,通过 reflex.Value 类型,可以获取到关于该变量的很多信息。

c 变量、interface{} 和 reflect.Value 是可以相互转换的,这点在实际开发中,会经常使用到。示意图如下。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值