golang reflect Pointer 获取 传入的interface信息
使用反射可以获取到数据的类型信息,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信息相关推荐
- java爬取验证码图片_JAVA HttpClient实现页面信息抓取(获取图片验证码并传入cookie实现信息获取)...
JAVA HttpClient实现页面信息抓取(获取图片验证码并传入cookie实现信息获取) 发布时间:2018-05-18 16:41, 浏览次数:632 , 标签: JAVA HttpClien ...
- Go的反射是如何获取结构体成员信息的?
前言 哈喽,大家好,今天这篇文章的目的主要是解答一位读者的疑问,涉及知识点是反射和结构体内存布局.我们先看一下读者的问题: img 我们通过两个问题来解决他的疑惑: 结构体在内存中是如何存储的 反射获 ...
- golang 面试题(十三)interface内部结构和nil详解
1.以下代码打印出来什么内容,说出为什么. package mainimport ("fmt" )type People interface {Show() }type Stude ...
- 阿里云视频点播获取视频点播的video信息
背景 因为在项目中需要使用阿里云的视频点播服务,需要获取视频点播的时长信息. 工具类 生成签名串Signature SignatureUtils.java package com.meeno.wzq. ...
- golang reflect 反射 简介
和Java语言一样,Go也实现运行时反射,这为我们提供一种可以在运行时操作任意类型对象的能力.比如我们可以查看一个接口变量的具体类型,看看一个结构体有多少字段,如何修改某个字段的值等等. TypeOf ...
- golang reflect
reflect包实现了运行时反射,允许程序操作任意类型的对象.典型用法是用静态类型interface{}保存一个值,通过调用TypeOf获取其动态类型信息,该函数返回一个Type类型值.调用Value ...
- SUMO使用E2检测器获取信号交叉口车道信息和信号控制方案
文章目录 前言 一.Traci接口是什么 二.获取方法 1.建立路网.车流和检测器 2.调用traci接口,启动仿真 3.获取车道转向信息 4.通过E2检测器获得车道信息 5.获取每个相位放行车道信息 ...
- java根据IP获取当前区域天气信息
java根据IP获取当前区域天气信息 大致思路是客户端发起请求,我们首先根据请求获取到外网IP,然后再根据外网IP获取到用户所在城市,最后根据城市获取到天气信息 获取外网IP 万网获取外网IP地址: ...
- 朝花夕拾:代码生成器的基础——获取数据源的架构信息
最近在做一个代码生成工具,在制作的过程中,掌握了获取数据源的架构信息,获取数据源的架构信息是代码生成工具的基础. 获取数据源的架构信息,网上有不同的方法,但我觉得都太复杂了,其实在.Net上,要获取数 ...
最新文章
- SMA携手LG推出住宅光伏储能逆变器
- 64位系统识别内存 服务器,服务器内存和电脑内存的区别
- MYSQL-用户操作
- 关于Faster R-CNN的一切——笔记3:Faster R-CNN
- Druid 配置_配置WebStatFilter
- 编程判断元素归类_编程练习-判断是否为易混淆数
- 【Kotlin】我的第一个 Kotlin 程序
- 深度学习这么调参训练_深度学习训练的小技巧,调参经验(转)
- 如何让service不被系统杀掉
- hibernate clob mysql_Hibernate操作Clob类型数据
- C++新特性探究(十七):chrono计時器
- Assembly generation failed Referenced assembly ‘xxx’ does not have a strong name
- ultrascale和arm区别_UltraScale+MPSoC软硬件设计及入门套件
- 【交换机在江湖】第十章 接口配置锦囊妙计之二----端口隔离
- scratch课程案例——时钟
- 分享一个很好的dll查看器
- 解决 Sketch 在MAC M1上运行卡顿等问题!
- 量化投资必备手册:史上超全量化交易平台汇总
- AI编程 亚马逊 CodeWhisperer VS GitHub Copilot
- java计算机毕业设计乒乓球俱乐部管理源码+系统+数据库+lw文档+mybatis+运行部署