使用反射可以获取到数据的类型信息,reflect.TypeOf()返回的数据类型如下:

type rtype struct {size       uintptrptrdata    uintptr  // number of bytes in the type that can contain pointershash       uint32   // hash of type; avoids computation in hash tablestflag      tflag    // extra type information flagsalign      uint8    // alignment of variable with this typefieldAlign uint8    // alignment of struct field with this typekind       uint8    // enumeration for Calg        *typeAlg // algorithm tablegcdata     *byte    // garbage collection datastr        nameOff  // string formptrToThis  typeOff  // type for pointer to this type, may be zero
}

这里我们常用到的是size(大小)、kind(底层类型名称)。

对于结构体,我们可以使用Field(i)方法获取到结构体中每个元素的信息,返回的数据类型如下:

type StructField struct {// Name is the field name.Name string// PkgPath is the package path that qualifies a lower case (unexported)// field name. It is empty for upper case (exported) field names.// See https://golang.org/ref/spec#Uniqueness_of_identifiersPkgPath stringType      Type      // field typeTag       StructTag // field tag stringOffset    uintptr   // offset within struct, in bytesIndex     []int     // index sequence for Type.FieldByIndexAnonymous bool      // is an embedded field
}

这里我们常用到的是Type(类型信息结构体)、Offset(偏移量)。

对于数组和切片,我们可以使用Elem()方法获取到每个元素的类型,返回的数据为Type类型,因为数组中的每个元素的类型都是一样的,所以偏移量也都一致,使用Size()方法获取即可。

通常我们使用unsafe.Pointer来获取某个数据的地址,但是unsafe.Pointer是无法进行计算的,它只是个单纯的指针类型,因此无法计算偏移量,这时候就需要使用uintptr了。因为uintptr底层是个整形,所以可以直接用来计算偏移量,而且unsafe.Pointer与uintptr是可以相互转换的。

有了上面这些工具,那么就可以愉快地获取数据类型的信息了。

实例:

type Game struct {name     stringgameType stringprice    int
}func main() {//Obj := []int{11,12,13,14,15,16}//Obj := []byte("我朋友需要268块做手术.jpg")Obj := Game{name:     "条狗:无限影逝",gameType: "ACT",price:    268,}ObjectPtr := unsafe.Pointer(&Obj) //获取obj起始位置ObjectType := reflect.TypeOf(Obj) //获取obj类型switch ObjectType.Kind() {case reflect.Struct:{for i := 0; i < ObjectType.NumField(); i++ { //遍历结构体内所有元素fd := ObjectType.Field(i)switch fd.Type.Kind() { //获取当前元素的类型case reflect.String:fmt.Println(*(*string)(unsafe.Pointer(uintptr(ObjectPtr) + uintptr(fd.Offset)))) //计算偏移量case reflect.Int:fmt.Println(*(*int)(unsafe.Pointer(uintptr(ObjectPtr) + uintptr(fd.Offset))))//判断其他Kind}}}case reflect.Slice:{SlicePtr := (*reflect.SliceHeader)(ObjectPtr)fieldPtr := unsafe.Pointer(SlicePtr.Data)ElemType := ObjectType.Elem() //intfor i := 0; i < SlicePtr.Len; i++ {switch ElemType.Kind() {case reflect.Int:fmt.Println(*(*int)(unsafe.Pointer(uintptr(fieldPtr) + uintptr(i*int(ElemType.Size())))))case reflect.Uint8:fmt.Println(*(*uint8)(unsafe.Pointer(uintptr(fieldPtr) + uintptr(i*int(ElemType.Size())))))//判断其他Kind}}}//判断其他Kind}
}

golang reflect Pointer 获取 传入的interface信息相关推荐

  1. java爬取验证码图片_JAVA HttpClient实现页面信息抓取(获取图片验证码并传入cookie实现信息获取)...

    JAVA HttpClient实现页面信息抓取(获取图片验证码并传入cookie实现信息获取) 发布时间:2018-05-18 16:41, 浏览次数:632 , 标签: JAVA HttpClien ...

  2. Go的反射是如何获取结构体成员信息的?

    前言 哈喽,大家好,今天这篇文章的目的主要是解答一位读者的疑问,涉及知识点是反射和结构体内存布局.我们先看一下读者的问题: img 我们通过两个问题来解决他的疑惑: 结构体在内存中是如何存储的 反射获 ...

  3. golang 面试题(十三)interface内部结构和nil详解

    1.以下代码打印出来什么内容,说出为什么. package mainimport ("fmt" )type People interface {Show() }type Stude ...

  4. 阿里云视频点播获取视频点播的video信息

    背景 因为在项目中需要使用阿里云的视频点播服务,需要获取视频点播的时长信息. 工具类 生成签名串Signature SignatureUtils.java package com.meeno.wzq. ...

  5. golang reflect 反射 简介

    和Java语言一样,Go也实现运行时反射,这为我们提供一种可以在运行时操作任意类型对象的能力.比如我们可以查看一个接口变量的具体类型,看看一个结构体有多少字段,如何修改某个字段的值等等. TypeOf ...

  6. golang reflect

    reflect包实现了运行时反射,允许程序操作任意类型的对象.典型用法是用静态类型interface{}保存一个值,通过调用TypeOf获取其动态类型信息,该函数返回一个Type类型值.调用Value ...

  7. SUMO使用E2检测器获取信号交叉口车道信息和信号控制方案

    文章目录 前言 一.Traci接口是什么 二.获取方法 1.建立路网.车流和检测器 2.调用traci接口,启动仿真 3.获取车道转向信息 4.通过E2检测器获得车道信息 5.获取每个相位放行车道信息 ...

  8. java根据IP获取当前区域天气信息

    java根据IP获取当前区域天气信息 大致思路是客户端发起请求,我们首先根据请求获取到外网IP,然后再根据外网IP获取到用户所在城市,最后根据城市获取到天气信息 获取外网IP 万网获取外网IP地址: ...

  9. 朝花夕拾:代码生成器的基础——获取数据源的架构信息

    最近在做一个代码生成工具,在制作的过程中,掌握了获取数据源的架构信息,获取数据源的架构信息是代码生成工具的基础. 获取数据源的架构信息,网上有不同的方法,但我觉得都太复杂了,其实在.Net上,要获取数 ...

最新文章

  1. SMA携手LG推出住宅光伏储能逆变器
  2. 64位系统识别内存 服务器,服务器内存和电脑内存的区别
  3. MYSQL-用户操作
  4. 关于Faster R-CNN的一切——笔记3:Faster R-CNN
  5. Druid 配置_配置WebStatFilter
  6. 编程判断元素归类_编程练习-判断是否为易混淆数
  7. 【Kotlin】我的第一个 Kotlin 程序
  8. 深度学习这么调参训练_深度学习训练的小技巧,调参经验(转)
  9. 如何让service不被系统杀掉
  10. hibernate clob mysql_Hibernate操作Clob类型数据
  11. C++新特性探究(十七):chrono计時器
  12. Assembly generation failed Referenced assembly ‘xxx’ does not have a strong name
  13. ultrascale和arm区别_UltraScale+MPSoC软硬件设计及入门套件
  14. 【交换机在江湖】第十章 接口配置锦囊妙计之二----端口隔离
  15. scratch课程案例——时钟
  16. 分享一个很好的dll查看器
  17. 解决 Sketch 在MAC M1上运行卡顿等问题!
  18. 量化投资必备手册:史上超全量化交易平台汇总
  19. AI编程 亚马逊 CodeWhisperer VS GitHub Copilot
  20. java计算机毕业设计乒乓球俱乐部管理源码+系统+数据库+lw文档+mybatis+运行部署

热门文章

  1. 微服务架构 — 服务治理 — 服务注册与发现、服务订阅与通知
  2. 使用VSCode编辑Markdown
  3. 使用MQTT.fx(mqttfx软件)接入阿里云
  4. altium designer PCB 屏蔽DRC报错
  5. 使用Gunicorn Ngnx Supervisor部署Django项目
  6. Python中range和xrange的区别
  7. 刷牙刷了这么多年,我们居然都搞错了!
  8. Android 程序自动更新功能模块实现
  9. 细说JavaScript异步函数发展历程
  10. Android handler