任意值通过 reflect.TypeOf() 获得反射对象信息后,如果它的类型是结构体,可以通过反射值对象(reflect.Type)的 NumField() 和 Field() 方法获得结构体成员的详细信息。与成员获取相关的 reflect.Type 的方法如下表所示。

结构体成员访问的方法列表

方法

说明

Field(i int) StructField

根据索引,返回索引对应的结构体字段的信息。当值不是结构体或索引超界时发生宕机

NumField() int

返回结构体成员字段数量。当类型不是结构体或索引超界时发生宕机

FieldByName(name string) (StructField, bool)

根据给定字符串返回字符串对应的结构体字段的信息。没有找到时 bool 返回 false,当类型不是结构体或索引超界时发生宕机

FieldByIndex(index []int) StructField

多层成员访问时,根据 []int 提供的每个结构体的字段索引,返回字段的信息。没有找到时返回零值。当类型不是结构体或索引超界时 发生宕机

FieldByNameFunc( match func(string) bool) (StructField,bool)

根据匹配函数匹配需要的字段。当值不是结构体或索引超界时发生宕机

结构体字段类型

reflect.Type 的 Field() 方法返回 StructField 结构,这个结构描述结构体的成员信息,通过这个信息可以获取成员与结构体的关系,如偏移、索引、是否为匿名字段、结构体标签(Struct Tag)等,而且还可以通过 StructField 的 Type 字段进一步获取结构体成员的类型信息。StructField 的结构如下:

type StructField struct {

Name string // 字段名

PkgPath string // 字段路径

Type Type // 字段反射类型对象

Tag StructTag // 字段的结构体标签

Offset uintptr // 字段在结构体中的相对偏移

Index []int // Type.FieldByIndex中的返回的索引值

Anonymous bool // 是否为匿名字段

}

字段说明如下。

Name:为字段名称。

PkgPath:字段在结构体中的路径。

Type:字段本身的反射类型对象,类型为 reflect.Type,可以进一步获取字段的类型信息。

Tag:结构体标签,为结构体字段标签的额外信息,可以单独提取。

Index:FieldByIndex 中的索引顺序。

Anonymous:表示该字段是否为匿名字段。

获取成员反射信息

下面代码中,实例化一个结构体并遍历其结构体成员,再通过 reflect.Type 的 FieldByName() 方法查找结构体中指定名称的字段,直接获取其类型信息。

反射访问结构体成员类型及信息:

package main

import (

"fmt"

"reflect"

)

func main() {

// 声明一个空结构体

type cat struct {

Name string

// 带有结构体tag的字段

Type int `json:"type" id:"100"`

}

// 创建cat的实例

ins := cat{Name: "mimi", Type: 1}

// 获取结构体实例的反射类型对象

typeOfCat := reflect.TypeOf(ins)

// 遍历结构体所有成员

for i := 0; i < typeOfCat.NumField(); i++ {

// 获取每个成员的结构体字段类型

fieldType := typeOfCat.Field(i)

// 输出成员名和tag

fmt.Printf("name: %v tag: '%v'\n", fieldType.Name, fieldType.Tag)

}

// 通过字段名, 找到字段类型信息

if catType, ok := typeOfCat.FieldByName("Type"); ok {

// 从tag中取出需要的tag

fmt.Println(catType.Tag.Get("json"), catType.Tag.Get("id"))

}

}

代码输出如下:

name: Name  tag: ''

name: Type  tag: 'json:"type" id:"100"'

type 100

代码说明如下:

第 11 行,声明了带有两个成员的 cat 结构体。

第 15 行,Type 是 cat 的一个成员,这个成员类型后面带有一个以`开始和结尾的字符串。这个字符串在 Go 语言中被称为 Tag(标签)。一般用于给字段添加自定义信息,方便其他模块根据信息进行不同功能的处理。

第 19 行,创建 cat 实例,并对两个字段赋值。结构体标签属于类型信息,无须且不能赋值。

第 22 行,获取实例的反射类型对象。

第 25 行,使用 reflect.Type 类型的 NumField() 方法获得一个结构体类型共有多少个字段。如果类型不是结构体,将会触发宕机错误。

第 28 行,reflect.Type 中的 Field() 方法和 NumField 一般都是配对使用,用来实现结构体成员的遍历操作。

第 31 行,使用 reflect.Type 的 Field() 方法返回的结构不再是 reflect.Type 而是StructField 结构体。

第 35 行,使用 reflect.Type 的 FieldByName() 根据字段名查找结构体字段信息,cat Type 表示返回的结构体字段信息,类型为 StructField,ok 表示是否找到结构体字段的信息。

第 38 行中,使用 StructField 中 Tag 的 Get() 方法,根据 Tag 中的名字进行信息获取。

c语言 typeof 结构体,Go语言通过反射获取结构体的成员类型相关推荐

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

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

  2. C++:C++语言入门级基础知识考察点回顾之函数、结构体和类

    C++:C++语言入门级基础知识考察点回顾之函数.结构体和类 目录 C++的函数 1.函数的定义.调用,全局变量局部变量 1.1.自定义函数求其倒数

  3. C语言如何获取结构体中指定元素的大小?sizeof ( (X*)0 ) -> Y)(空指针操作)

    获取结构体的大小,这好办,这样就可以了: #include <stdio.h>struct user {char name[20];char age[10]; };int main() { ...

  4. 一文攻破结构体-C语言

    一文攻破结构体-C语言 1 什么是结构体 1.1 结构体类型 结构体(structure)是由不同类型数据组成的组合型的数据结构,可以看做变量的集合.结构体也是一个数据类型,就像和 int.char一 ...

  5. 《零基础看得懂的C语言入门教程 》——(十二)原来结构体是这么回事

    一.学习目标 了解C语言的结构体的使用方法 了解C语言结构体的结构的赋值 了解多种C语言结构体变量的赋值方法和取值方法 目录 C语言真的很难吗?那是你没看这张图,化整为零轻松学习C语言. 第一篇:(一 ...

  6. c++ new一个结构体_C语言结构体,又一个纸老虎,纯干货讲解(附代码)

    来源:网络,排版整理:晓宇 微信公众号:芯片之家(ID:chiphome-dy)结构体的定义结构体(struct)是由一系列具有相同类型或不同类型的数据构成的数据集合,也叫结构.结构体和其他类型基础数 ...

  7. c语言sqlist结构体,c语言里 sqlist

    满意答案 cielkong 2018.08.12 采纳率:43%    等级:9 已帮助:463人 c语言里 sqlist?//定义顺序表L的结构体 typedef struct { Elemtype ...

  8. 【C语言笔记初级篇】第七章:结构体相关

    目录 (1)结构体的声明,定义,初始化和成员访问 A:什么是结构体 B:结构体声明和定义 C:结构体的初始化 D:成员访问 (2)结构体传参 (3)结构体自引用 (4)内存对齐 (5)结构体传参 (6 ...

  9. 结构体嵌套结构体c语言,结构体的相互嵌套

    编程时要用到C语言中结构体的自引用,由于用的少,学得时候也没在意,趁用到,回忆一下. 结构体的自引用(self reference),就是在结构体内部,包含指向自身类型结构体的指针. 结构体的相互引用 ...

最新文章

  1. 企业安全体系建设方案设计(内附案例)
  2. 简单的客户端,服务端通信
  3. Matlab中imagesc用法
  4. Python开发【Part 11】:线程与进程
  5. linux安装软件包(pip, distribute, nose, virtualenv)
  6. Exynos4412 裸机开发 —— IIC总线
  7. CSDN如何找到自己关注的博客专栏
  8. Error running ‘Unnamed‘: Unable to open debugger port (127.0.0.1:xxxx)
  9. HDU 1257 最少拦截系统 简单DP
  10. 有意思的堪称世界级的电视广告!!:)
  11. MSA移动安全联盟 获取OAID 异常问题
  12. 怎么设计一种雷达成像系统代码_光纤阵列成像激光雷达系统的设计
  13. 给定一个字符串,去除整个字符串中重复的字符
  14. 分析在各大考纲词汇中既没有词根也没有前缀和后缀的独立单词
  15. 删除字符串中的元音字母
  16. 【BUCTOJ训练: 求和(Python)】
  17. Web前端第三阶段--DOM
  18. 如何剪辑QQ酷狗下载的音乐?
  19. 【敏捷4.2】相关方的沟通与协同
  20. Java 爬虫工具Jsoup解析

热门文章

  1. Linux export 命令用法
  2. leetcode 169. 多数元素(不同数相消解法)
  3. 个人博客 | 网站部署终极操作:一行命令搞定!
  4. 【Apscheduler】不生效也不报错,提示No handlers could be found for logger “apscheduler.executors.default”
  5. 算法设计与分析【第七周】贪心算法 活动安排问题
  6. dart系列之:时间你慢点走,我要在dart中抓住你
  7. 懂集合吗?对,是dart中的集合
  8. vs unity shader插件_一些Shader资料
  9. python -- 计算 平方、乘方、平方根_从零开始学习PYTHON3讲义(二)把Python当做计算器...
  10. jsp Request获取url信息的各种方法比较