iis服务器助手广告
返回顶部
首页 > 资讯 > 精选 >Go如何利用反射reflect实现获取接口变量信息
  • 233
分享到

Go如何利用反射reflect实现获取接口变量信息

2023-06-30 16:06:58 233人浏览 泡泡鱼
摘要

本篇内容主要讲解“Go如何利用反射reflect实现获取接口变量信息”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Go如何利用反射reflect实现获取接口变量信息”吧!引言反射是通过实体对象获

本篇内容主要讲解“Go如何利用反射reflect实现获取接口变量信息”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Go如何利用反射reflect实现获取接口变量信息”吧!

    引言

    反射是通过实体对象获取反射对象(Value、Type),然后可以操作相应的方法。在某些情况下,我们可能并不知道变量的具体类型,这时候就可以用反射来获取这个变量的类型或者方法。

    一、反射的规则

    其实反射的操作步骤非常的简单,就是通过实体对象获取反射对象(Value、Type),然后操作相应的方法即可。

    下图描述了实例、Value、Type 三者之间的转换关系:

    Go如何利用反射reflect实现获取接口变量信息

    反射 api 的分类总结如下:

    1、从实例到 Value

    通过实例获取 Value 对象,直接使用 reflect.ValueOf() 函数。例如:

    func ValueOf(i interface {}) Value

    2、从实例到 Type

    通过实例获取反射对象的 Type,直接使用 reflect.TypeOf() 函数。例如:

    func TypeOf(i interface{}) Type

    3、从 Type 到 Value

    Type 里面只有类型信息,所以直接从一个 Type 接口变量里面是无法获得实例的 Value 的,但可以通过该 Type 构建一个新实例的 Value。reflect 包提供了两种方法,示例如下:

    //New 返回的是一个 Value,该 Value 的 type 为 PtrTo(typ),即 Value 的 Type 是指定 typ 的指针类型func New(typ Type) Value//Zero 返回的是一个 typ 类型的零佳,注意返回的 Value 不能寻址,位不可改变func Zero(typ Type) Value

    如果知道一个类型值的底层存放地址,则还有一个函数是可以依据 type 和该地址值恢复出 Value 的。例如:

    func NewAt(typ Type, p unsafe.Pointer) Value

    4、从 Value 到 Type

    从反射对象 Value 到 Type 可以直接调用 Value 的方法,因为 Value 内部存放着到 Type 类型的指针。例如:

    func (v Value) Type() Type

    5、从 Value 到实例

    Value 本身就包含类型和值信息,reflect 提供了丰富的方法来实现从 Value 到实例的转换。例如:

    //该方法最通用,用来将 Value 转换为空接口,该空接口内部存放具体类型实例//可以使用接口类型查询去还原为具体的类型func (v Value) Interface() (i interface{})//Value 自身也提供丰富的方法,直接将 Value 转换为简单类型实例,如果类型不匹配,则直接引起 panicfunc (v Value) Bool () boolfunc (v Value) Float() float64func (v Value) Int() int64func (v Value) Uint() uint64

    6、从 Value 的指针到值

    从一个指针类型的 Value 获得值类型 Value 有两种方法,示例如下。

    //如果 v 类型是接口,则 Elem() 返回接口绑定的实例的 Value,如采 v 类型是指针,则返回指针值的 Value,否则引起 panicfunc (v Value) Elem() Value//如果 v 是指针,则返回指针值的 Value,否则返回 v 自身,该函数不会引起 panicfunc Indirect(v Value) Value

    7、Type 指针和值的相互转换

    指针类型 Type 到值类型 Type。例如:

    //t 必须是 Array、Chan、Map、Ptr、Slice,否则会引起 panic//Elem 返回的是其内部元素的 Typet.Elem() Type

    值类型 Type 到指针类型 Type。例如:

    //PtrTo 返回的是指向 t 的指针型 Typefunc PtrTo(t Type) Type

    8、Value 值的可修改性

    Value 值的修改涉及如下两个方法:

    //通过 CanSet 判断是否能修改func (v Value ) CanSet() bool//通过 Set 进行修改func (v Value ) Set(x Value)

    Value 值在什么情况下可以修改?我们知道实例对象传递给接口的是一个完全的值拷贝,如果调用反射的方法 reflect.ValueOf() 传进去的是一个值类型变量, 则获得的 Value 实际上是原对象的一个副本,这个 Value 是无论如何也不能被修改的。

    9、根据 Go 官方关于反射的文档,反射有三大定律:9

    • Reflection goes from interface value to reflection object.

    • Reflection goes from reflection object to interface value.

    • To modify a reflection object, the value must be settable.

    第一条是最基本的:反射可以从接口值得到反射对象。

    反射是一种检测存储在 interface中的类型和值机制。这可以通过 TypeOf函数和 ValueOf函数得到。

    第二条实际上和第一条是相反的机制,反射可以从反射对象获得接口值。

    它将 ValueOf的返回值通过 Interface()函数反向转变成 interface变量。

    前两条就是说 接口型变量和 反射类型对象可以相互转化,反射类型对象实际上就是指的前面说的 reflect.Type和 reflect.Value。

    第三条不太好懂:如果需要操作一个反射变量,则其值必须可以修改。

    反射变量可设置的本质是它存储了原变量本身,这样对反射变量的操作,就会反映到原变量本身;反之,如果反射变量不能代表原变量,那么操作了反射变量,不会对原变量产生任何影响,这会给使用者带来疑惑。所以第二种情况在语言层面是不被允许的。

    二、反射的使用

    从relfect.Value中获取接口interface的信息

    当执行reflect.ValueOf(interface)之后,就得到了一个类型为”relfect.Value”变量,可以通过它本身的Interface()方法获得接口变量的真实内容,然后可以通过类型判断进行转换,转换为原有真实类型。不过,我们可能是已知原有类型,也有可能是未知原有类型,因此,下面分两种情况进行说明。

    1、已知原有类型

    已知类型后转换为其对应的类型的做法如下,直接通过Interface方法然后强制转换,如下:

    realValue := value.Interface().(已知的类型)

    示例代码:

    package mainimport (    "fmt"    "reflect")func main() {    var num float64 = 3.1415926    pointer := reflect.ValueOf(&num)    value := reflect.ValueOf(num)    // 可以理解为“强制转换”,但是需要注意的时候,转换的时候,如果转换的类型不完全符合,则直接panic    // golang 对类型要求非常严格,类型一定要完全符合    // 如下两个,一个是*float64,一个是float64,如果弄混,则会panic    convertPointer := pointer.Interface().(*float64)    convertValue := value.Interface().(float64)    fmt.Println(convertPointer)    fmt.Println(convertValue)}

    运行结果:

    0xc000018080
    3.1415926

    说明

    • 转换的时候,如果转换的类型不完全符合,则直接panic,类型要求非常严格!

    • 转换的时候,要区分是指针还是指

    • 也就是说反射可以将“反射类型对象”再重新转换为“接口类型变量”

    2、未知原有类型

    很多情况下,我们可能并不知道其具体类型,那么这个时候,该如何做呢?需要我们进行遍历探测其Filed来得知,示例如下:

    package mainimport (    "fmt"    "reflect")type Person struct {    Name string    Age int    Sex string}func (p Person)Say(msg string)  {    fmt.Println("hello,",msg)}func (p Person)PrintInfo()  {    fmt.Printf("姓名:%s,年龄:%d,性别:%s\n",p.Name,p.Age,p.Sex)}func main() {    p1 := Person{"王富贵",20,"男"}    DoFiledAndMethod(p1)}// 通过接口来获取任意参数func DoFiledAndMethod(input interface{}) {    getType := reflect.TypeOf(input) //先获取input的类型    fmt.Println("get Type is :", getType.Name()) // Person    fmt.Println("get Kind is : ", getType.Kind()) // struct    getValue := reflect.ValueOf(input)    fmt.Println("get all Fields is:", getValue) //{王富贵 20 男}    // 获取方法字段    // 1. 先获取interface的reflect.Type,然后通过NumField进行遍历    // 2. 再通过reflect.Type的Field获取其Field    // 3. 最后通过Field的Interface()得到对应的value    for i := 0; i < getType.NumField(); i++ {        field := getType.Field(i)        value := getValue.Field(i).Interface() //获取第i个值        fmt.Printf("字段名称:%s, 字段类型:%s, 字段数值:%v \n", field.Name, field.Type, value)    }    // 通过反射,操作方法    // 1. 先获取interface的reflect.Type,然后通过.NumMethod进行遍历    // 2. 再公国reflect.Type的Method获取其Method    for i := 0; i < getType.NumMethod(); i++ {        method := getType.Method(i)        fmt.Printf("方法名称:%s, 方法类型:%v \n", method.Name, method.Type)    }}

    运行结果:

    get Type is : Person
    get Kind is :  struct
    get all Fields is: {王富贵 20 男}
    字段名称:Name, 字段类型:string, 字段数值:王富贵 
    字段名称:Age, 字段类型:int, 字段数值:20 
    字段名称:Sex, 字段类型:string, 字段数值:男 
    方法名称:PrintInfo, 方法类型:func(main.Person) 
    方法名称:Say, 方法类型:func(main.Person, string) 

    到此,相信大家对“Go如何利用反射reflect实现获取接口变量信息”有了更深的了解,不妨来实际操作一番吧!这里是编程网网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

    --结束END--

    本文标题: Go如何利用反射reflect实现获取接口变量信息

    本文链接: https://www.lsjlt.com/news/330378.html(转载时请注明来源链接)

    有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

    本篇文章演示代码以及资料文档资料下载

    下载Word文档到电脑,方便收藏和打印~

    下载Word文档
    猜你喜欢
    • Go如何利用反射reflect实现获取接口变量信息
      本篇内容主要讲解“Go如何利用反射reflect实现获取接口变量信息”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Go如何利用反射reflect实现获取接口变量信息”吧!引言反射是通过实体对象获...
      99+
      2023-06-30
    • Thinkphp5微信小程序如何实现获取用户信息接口
      这篇文章主要为大家展示了“Thinkphp5微信小程序如何实现获取用户信息接口”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Thinkphp5微信小程序如何实现...
      99+
      2024-04-02
    • 如何使用 PHP 反射在函数中获取参数信息?
      php 反射可通过 reflectionfunction 类和 reflectionparameter 对象获取函数参数信息,包括:getname(): 参数名称gettype(): 参...
      99+
      2024-04-11
      php 反射
    • java利用反射机制如何实现获取对象的值
      本篇文章给大家分享的是有关java利用反射机制如何实现获取对象的值,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。通过反射机制得到对象中的属性和属性值 在对象中private没问...
      99+
      2023-05-31
      java 反射 对象
    • 利用java如何实现获取redis数据库的日志信息
      这篇文章给大家介绍利用java如何实现获取redis数据库的日志信息,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。效果展示如下所示:实时监控redis环境信息和日志列表Redis配置在windows下安装的redis,...
      99+
      2023-05-31
      java redis 日志
    • 如何在Android应用中利用Intent实现获取联系人的信息
      今天就跟大家聊聊有关如何在Android应用中利用Intent实现获取联系人的信息,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。Intent的使用intent是一个好东西他可以启动A...
      99+
      2023-05-31
      android intent
    • 利用Java如何获取Mybatis动态生成的sql接口实现
      目录前言1、编写xml: SqlGenarate.mapper.xml2、定义接口3、实现接口总结前言 如果你有使用 JDBC 或其他类似框架的经验,你就能体会到根据不同条件拼接 S...
      99+
      2024-04-02
    • 详解.NET6如何实现获取当前登录用户信息
      目录需求目标原理和思路实现创建当前用户获取接口实现接口功能使用功能验证总结需求 在前面的文章里使用.NET 6开发TodoList应用之领域实体创建原理和思路,我们留了一个...
      99+
      2024-04-02
    • 利用java如何实现一个微信APP支付接口
      这篇文章给大家介绍利用java如何实现一个微信APP支付接口,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。开始开发1、配置相关的配置信息1、配置appid(Android)、mch_id(ios)、微信支付后的回调地址...
      99+
      2023-05-31
      java 支付
    • 微信公众号开发中使用Java如何实现获取用户的信息
      微信公众号开发中使用Java如何实现获取用户的信息?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。首先需要到微信网站去设置一下,我是直接用的微信测试号。        接口配...
      99+
      2023-05-31
      java 微信公众号 用户信息
    • 如何使用spring动态获取接口的不同实现类
      这篇“如何使用spring动态获取接口的不同实现类”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“如何使用spring动态获取...
      99+
      2023-06-29
    • 微信公众平台开发中使用Java如何实现获取用户的信息
      本篇文章为大家展示了微信公众平台开发中使用Java如何实现获取用户的信息,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。(一)用户微信消息的获取实现在关注者与公众号产生消息交互后,公众号可获得关注者的...
      99+
      2023-05-31
      java 获取用户信息
    • 如何使用HTML5实现获取地理位置信息并定位功能
      小编给大家分享一下如何使用HTML5实现获取地理位置信息并定位功能,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧! 代码如下: function getLocation(){ if (...
      99+
      2024-04-02
    • 小程序开发中如何调用接口获取登录凭证进而换取用户登录态信息
      这篇文章主要为大家展示了小程序开发中如何调用接口获取登录凭证进而换取用户登录态信息,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带大家一起来研究并学习一下“小程序开发中如何调用接口获取登录凭证进而换取用户登录态信息”这篇文章...
      99+
      2023-06-26
    • 微信小程序如何实现获取用户信息替换用户名和头像到首页
      本篇内容介绍了“微信小程序如何实现获取用户信息替换用户名和头像到首页”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、形成空白文件点击打开...
      99+
      2023-06-30
    • vue中如何使用echarts实现动态数据绑定及获取后端接口数据
      本篇内容主要讲解“vue中如何使用echarts实现动态数据绑定及获取后端接口数据”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“vue中如何使用echarts实现动态数据绑定及获取后端接口数据”...
      99+
      2023-07-02
    软考高级职称资格查询
    编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
    • 官方手机版

    • 微信公众号

    • 商务合作