文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Golang reflect反射如何使用

2023-07-06 04:17

关注

这篇文章主要介绍“Golang reflect反射如何使用”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Golang reflect反射如何使用”文章能帮助大家解决问题。

首先有一段以下结构体的定义

type User struct {UserName stringUserId   int `name:"uid"`}

初始化一个结构体的实例

u := User{"octoboy", 101}

获取字段名

首先获取变量的Type变量

t := reflect.TypeOf(u)

需要注意的是,如果传入的u是个指针,比如&User{"octoboy", 101}

if t.Kind() == reflect.Ptr {t = t.Elem()}

这里通过Kind()函数获取变量的类型,判断如果类型为指针 需要使用Elem()获取指针指向的内容。

然后遍历结构体的字段,获取其字段名称

for i := 0; i < t.NumField(); i++ {fmt.Println(t.Field(i).Name)}

输出结果:

UserName

UserId

获取字段类型和值

v := reflect.ValueOf(u)if v.Kind() == reflect.Ptr { //类型为指针 需要取elemv = v.Elem()}

获取字段的值或者赋值,需要用到ValueOf方法

for i := 0; i < v.NumField(); i++ {//v.Field(i).Int() v.Field(i).String() 都可以把值返回出来,相当于断言 类型不匹配会直接panic//直接断成interface 任意类型fmt.Println(v.Field(i).Interface())}

输出结果:

zyg

101

继续输出成员变量的类型

for i := 0; i < v.NumField(); i++ {fmt.Println(v.Field(i).Kind())}

输出结果:

string

int

设置字段值

静态赋值

//设置字段值va := reflect.ValueOf(&u) //这里必须使用指针 否则后面调用Set无法使用无地址的值if va.Kind() == reflect.Ptr { //类型为指针 需要取elem 意为取它指向的内容值va = va.Elem()for i := 0; i < va.NumField(); i++ {//两种方法取设置字段的值,第二种更为统一if va.Field(i).Kind() == reflect.String {//重要 如果需要使用set取修改u中的值,需要在ValueOf中传入u的地址。否则会因为SetString使用了一个不能被寻址的值而造成panicva.Field(i).SetString("octoboy")}if va.Field(i).Kind() == reflect.Int {va.Field(i).Set(reflect.ValueOf(123))}}

interface切片映射成结构体(动态赋值)

//练手values := []interface{}{"octoboy", 123}for i := 0; i < va.NumField(); i++ {if reflect.ValueOf(values[i]).Kind() == va.Field(i).Kind() {va.Field(i).Set(reflect.ValueOf(values[i]))}}

打印以上两种结构题变量

输出结果:

&{octoboy 123}

进阶&mdash;map映射成结构体

有如下代码

//练习 把map映射成structset := map[string]interface{}{"UserName": "zyg","UserId":   101,"Age":      19,"Sex":      1,}user := &User{}MapToStruct(set, user)fmt.Println(user)

要求将map映射到user结构题中,即如果User的字段名如存在于map的key中,则将对应的value值赋给user结构题的成员变量

有如下实现

//str类型为interface{} 代表可以传入任意的结构体func MapToStruct(m map[string]interface{}, str interface{}) {val := reflect.ValueOf(str)if val.Kind() != reflect.Ptr {//必须是指针 否则无法用Set赋值panic(any("must be ptr!"))}val = val.Elem()if val.Kind() != reflect.Struct { //指针指向的必须是结构体panic(any("must be struct"))}for i := 0; i < val.NumField(); i++ {name := val.Type().Field(i).Name //value转type后取字段名称if v, ok := m[name]; ok {        //如果根据tag做映射,就使用val.Type().Field(i).Tag.Get("name")作为keyif reflect.ValueOf(v).Kind() == val.Field(i).Kind() {val.Field(i).Set(reflect.ValueOf(v))}}}}

关于“Golang reflect反射如何使用”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注编程网行业资讯频道,小编每天都会为大家更新不同的知识点。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     801人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     348人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     311人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     432人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     220人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯