GO语言使用之Reflect(反射)

本文介绍了Go语言中的反射(reflect)使用,从案例场景引入,详细阐述了反射的基本概念,包括获取变量类型、值,以及如何进行变量、interface与reflect.Value之间的转换。讨论了反射在动态调用函数、结构体序列化等场景的应用,并给出了一些关键函数的用法,如TypeOf和ValueOf。同时,文章提请注意使用反射时的细节和最佳实践,如Kind与Type的区别,以及如何通过反射修改变量的值。
摘要由CSDN通过智能技术生成

一、从案列场景引入反射

定义了两个函数test1和test2,定义一个适配器函数用作统一处理接口:
(1) 定义了两个函数

test1 := func(v1 int, v2 int) {
    t.Log(v1, v2)
}
test2 := func(v1 int, v2 int, s string) {
    t.Log(v1, v2, s)
}

(2) 定义一个适配器函数用作统一处理接口, 其大致结构如下:

bridge := func(call interface{
   }, args ...interface{}) {
 //内容       
}
//实现调用test1对应的函数
bridge(test1, 1, 2) 
//实现调用test2对应的函数
bridge(test2, 1, 2, "test2")

(3) 要求使用反射机制完成

package test
import (
    "testing"
     "reflect"       
)
/*反射的最佳实践*/


/*
3) 定义了两个函数test1和test2,定义一个适配器函数用作统一处理接口【了解】:
(1) 定义了两个函数
test1 := func(v1 int, v2 int) {
    t.Log(v1, v2)
}
test2 := func(v1 int, v2 int, s string) {
    t.Log(v1, v2, s)
}
(2) 定义一个适配器函数用作统一处理接口, 其大致结构如下:
bridge := func(call interface{}, args ...interface{}) {
 //内容       
}
//实现调用test1对应的函数
bridge(test1, 1, 2) 
//实现调用test2对应的函数
bridge(test2, 1, 2, "test2")

(3) 要求使用反射机制完成 
*/  


func TestReflectFunc(t *testing.T) {
    call1 := func(v1 int, v2 int) {
        t.Log(v1, v2)
    }
    call2 := func(v1 int, v2 int, s string) {
        t.Log(v1, v2, s)
    }
    var (
        function reflect.Value
        inValue  []reflect.Value
        n        int
    )
    bridge := func(call interface{}, args ...interface{}) {
        n = len(args)
        inValue = make([]reflect.Value, n)
        for i := 0; i < n; i++ {
            inValue[i] = reflect.ValueOf(args[i])
        }
        function = reflect.ValueOf(call)
        function.Call(inValue)
    }
    bridge(call1, 1, 2)
    bridge(call2, 1, 2, "test2")
}

二、反射的基本介绍

1、反射可以在运行时动态获取变量的各种信息, 比如变量的类型(type),类别(kind)
2、 如果是结构体变量,还可以获取到结构体本身的信息(包括结构体的字段、方法)
3、通过反射,可以修改变量的值,可以调用关联的方法。
4、使用反射,需要 import (“reflect”)
5、 示意图

这里写图片描述

三、反射的应用场景

1、反射常见应用场景有以下两种
不知道接口调用哪个函数,根据传入参数在运行时确定调用的具体接口,这种需要对函数或方法反射。例如以下这种桥接模式, 比如我前面提出问题。

第一个参数funcPtr以接口的形式传入函数指针,函数参数args以可变参数的形式传入,bridge函数中可以用反射来动态执行funcPtr函数
2、对结构体序列化时,如果结构体有指定Tag, 也会使用到反射生成对应的字符串。
这里写图片描述

四、反射重要的函数和概念

1、reflect.TypeOf(变量名),获取变量的类型,返回reflect.Type类型
2、reflect.ValueOf(变量名),获取变量的值,返回reflect.Value类型reflect.Value 是一个结构体类型。【看文档】, 通过reflect.Value,可以获取到关于该变量的很多信息
3、变量、interface{} 和 reflect.Value是可以相互转换的,这点在实际开发中,会经常使用到。

变量 interface{} 和reflect.Value()是可以相互转换的,
变量 interface{} 和valueOf()之间的转换
这里写图片描述
这里写图片描述

五、快速入门的案例

反射普通变量和结构体

//反射操作方法-基本数据类型float64
func reflectOper(b interf
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值