golang基础-反射获取(基础数据、结构体)、操作(基本类型、结构体、指针)、反射获取Tag

2024-08-31 22:48

本文主要是介绍golang基础-反射获取(基础数据、结构体)、操作(基本类型、结构体、指针)、反射获取Tag,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

        • 反射获取基本类型
        • 反射获取结构体
        • Elem反射操作基本类型
        • 反射调用结构体方法
        • Elem反射操作结构体
        • Elem反射获取tag
        • 练习例子

反射获取基本类型

反射:可以在运行时动态获取变量的相关信息
Import (“reflect”)

a. reflect.TypeOf,获取变量的类型,返回reflect.Type类型
b. reflect.ValueOf,获取变量的值,返回reflect.Value类型
c. reflect.Value.Kind,获取变量的类别,返回一个常量
d. reflect.Value.Interface(),转换成interface{}类型

    var x float64 = 3.4fmt.Println("type:", reflect.TypeOf(x))v := reflect.ValueOf(x)fmt.Println("value:", v)fmt.Println("type:", v.Type())fmt.Println("kind:", v.Kind())fmt.Println("value:", v.Float())fmt.Println(v.Interface())fmt.Printf("value is %5.2e\n", v.Interface())y := v.Interface().(float64)fmt.Println(y)

输出如下:

type: float64
value: 3.4
type: float64
kind: float64
value: 3.4
3.4
value is 3.40e+00
3.4
反射获取结构体
package mainimport ("fmt""reflect"
)type Student struct {Name  stringAge   intScore float32
}func test(b interface{}) {t := reflect.TypeOf(b)fmt.Println(t)v := reflect.ValueOf(b)fmt.Println(v)k := v.Kind()fmt.Println(k)iv := v.Interface()fmt.Println(iv)stu, ok := iv.(Student)if ok {fmt.Printf("%v %T\n", stu, stu)}
}func main() {var a Student = Student{Name:  "stu01",Age:   18,Score: 92,}test(a)
}

输出如下:

PS E:\golang\go_pro\src\safly> go run demo.go
main.Student
{stu01 18 92}
struct
{stu01 18 92}
{stu01 18 92} main.Student
PS E:\golang\go_pro\src\safly>
Elem反射操作基本类型

用来获取指针指向的变量,相当于:
var a *int;

func main() {var b int = 1b = 200testInt(&b)fmt.Println(b)
}//fv.Elem()用来获取指针指向的变量
func testInt(b interface{}) {val := reflect.ValueOf(b)val.Elem().SetInt(100)c := val.Elem().Int()fmt.Printf("get value  interface{} %d\n", c)fmt.Printf("string val:%d\n", val.Elem().Int())
}

输出如下:

PS E:\golang\go_pro\src\safly> go run demo.go
get value  interface{} 100
string val:100
100
PS E:\golang\go_pro\src\safly>
反射调用结构体方法
package mainimport ("fmt""reflect"
)type Student struct {Name  stringAge   intScore float32}func (s Student) Print(){fmt.Println(s)
}func (s Student) Set(name string,age int,score float32){s.Age = ages.Name = names.Score = score
}func TestStruct(a interface{}) {val := reflect.ValueOf(a)kd := val.Kind()fmt.Println(val,kd)if kd != reflect.Struct {fmt.Println("expect struct")return}//获取字段数量fields:= val.NumField()fmt.Printf("struct has %d field\n",fields)//获取字段的类型for i:=0;i<fields;i++{fmt.Printf("%d %v\n",i,val.Field(i).Kind())}//获取方法数量methods:=val.NumMethod()fmt.Printf("struct has %d methods\n",methods)//反射调用的Print方法var params []reflect.Valueval.Method(0).Call(params)}func main() {var a Student = Student{Name:  "stu01",Age:   18,Score: 92.8,}TestStruct(a)// fmt.Println(a)
}

输出如下:

PS E:\golang\go_pro\src\safly> go run demo.go
{stu01 18 92.8} struct
struct has 3 field
0 string
1 int
2 float32
struct has 2 methods
{stu01 18 92.8}
PS E:\golang\go_pro\src\safly>
Elem反射操作结构体
package mainimport ("fmt""reflect"
)type Student struct {Name  stringAge   intScore float32}func (s Student) Print(){fmt.Println(s)
}func (s Student) Set(name string,age int,score float32){s.Age = ages.Name = names.Score = score
}func TestStruct(a interface{}) {val := reflect.ValueOf(a)kd := val.Kind()fmt.Println(val,kd)if kd!= reflect.Ptr && val.Elem().Kind() ==  reflect.Struct {fmt.Println("expect struct")return}//获取字段数量fields:= val.Elem().NumField()fmt.Printf("struct has %d field\n",fields)//获取字段的类型for i:=0;i<fields;i++{fmt.Printf("%d %v\n",i,val.Elem().Field(i).Kind())}//获取方法数量methods:=val.NumMethod()fmt.Printf("struct has %d methods\n",methods)//反射调用的Print方法var params []reflect.Valueval.Elem().Method(0).Call(params)
}func main() {var a Student = Student{Name:  "stu01",Age:   18,Score: 92.8,}TestStruct(&a)// fmt.Println(a)
}

输出如下:

PS E:\golang\go_pro\src\safly> go run demo.go
&{stu01 18 92.8} ptr
struct has 3 field
0 string
1 int
2 float32
struct has 2 methods
{stu01 18 92.8}
PS E:\golang\go_pro\src\safly>
Elem反射获取tag
package mainimport ("fmt""reflect"
)type Student struct {Name  string `json:"stu_name"`Age   intScore float32}func (s Student) Print(){fmt.Println(s)
}func (s Student) Set(name string,age int,score float32){s.Age = ages.Name = names.Score = score
}func TestStruct(a interface{}) {typ := reflect.TypeOf(a)tag := typ.Elem().Field(0).Tag.Get("json")fmt.Printf("Tag:%s\n",tag)
}func main() {var a Student = Student{Name:  "stu01",Age:   18,Score: 92.8,}TestStruct(&a)
}

输出如下:

PS E:\golang\go_pro\src\safly> go run demo.go
Tag:stu_name
PS E:\golang\go_pro\src\safly>
练习例子
package mainimport ("fmt""reflect"
)type T struct {A intB string
}func main() {t := T{23, "skidoo"}s := reflect.ValueOf(&t).Elem()typeOfT := s.Type()for i := 0; i < s.NumField(); i++ {f := s.Field(i)fmt.Printf("%d: %s %s = %v\n", i,typeOfT.Field(i).Name, f.Type(), f.Interface())}s.Field(0).SetInt(77)s.Field(1).SetString("Sunset Strip")fmt.Println("t is now", t)
}

输出如下:

PS E:\golang\go_pro\src\safly> go run demo.go
0: A int = 23
1: B string = skidoo
t is now {77 Sunset Strip}
PS E:\golang\go_pro\src\safly>

这篇关于golang基础-反射获取(基础数据、结构体)、操作(基本类型、结构体、指针)、反射获取Tag的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1125213

相关文章

SQL Server修改数据库名及物理数据文件名操作步骤

《SQLServer修改数据库名及物理数据文件名操作步骤》在SQLServer中重命名数据库是一个常见的操作,但需要确保用户具有足够的权限来执行此操作,:本文主要介绍SQLServer修改数据... 目录一、背景介绍二、操作步骤2.1 设置为单用户模式(断开连接)2.2 修改数据库名称2.3 查找逻辑文件名

C++中RAII资源获取即初始化

《C++中RAII资源获取即初始化》RAII通过构造/析构自动管理资源生命周期,确保安全释放,本文就来介绍一下C++中的RAII技术及其应用,具有一定的参考价值,感兴趣的可以了解一下... 目录一、核心原理与机制二、标准库中的RAII实现三、自定义RAII类设计原则四、常见应用场景1. 内存管理2. 文件操

mapstruct中的@Mapper注解的基本用法

《mapstruct中的@Mapper注解的基本用法》在MapStruct中,@Mapper注解是核心注解之一,用于标记一个接口或抽象类为MapStruct的映射器(Mapper),本文给大家介绍ma... 目录1. 基本用法2. 常用属性3. 高级用法4. 注意事项5. 总结6. 编译异常处理在MapSt

canal实现mysql数据同步的详细过程

《canal实现mysql数据同步的详细过程》:本文主要介绍canal实现mysql数据同步的详细过程,本文通过实例图文相结合给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的... 目录1、canal下载2、mysql同步用户创建和授权3、canal admin安装和启动4、canal

SQL中JOIN操作的条件使用总结与实践

《SQL中JOIN操作的条件使用总结与实践》在SQL查询中,JOIN操作是多表关联的核心工具,本文将从原理,场景和最佳实践三个方面总结JOIN条件的使用规则,希望可以帮助开发者精准控制查询逻辑... 目录一、ON与WHERE的本质区别二、场景化条件使用规则三、最佳实践建议1.优先使用ON条件2.WHERE用

SpringBoot服务获取Pod当前IP的两种方案

《SpringBoot服务获取Pod当前IP的两种方案》在Kubernetes集群中,SpringBoot服务获取Pod当前IP的方案主要有两种,通过环境变量注入或通过Java代码动态获取网络接口IP... 目录方案一:通过 Kubernetes Downward API 注入环境变量原理步骤方案二:通过

MyBatis ResultMap 的基本用法示例详解

《MyBatisResultMap的基本用法示例详解》在MyBatis中,resultMap用于定义数据库查询结果到Java对象属性的映射关系,本文给大家介绍MyBatisResultMap的基本... 目录MyBATis 中的 resultMap1. resultMap 的基本语法2. 简单的 resul

从基础到进阶详解Pandas时间数据处理指南

《从基础到进阶详解Pandas时间数据处理指南》Pandas构建了完整的时间数据处理生态,核心由四个基础类构成,Timestamp,DatetimeIndex,Period和Timedelta,下面我... 目录1. 时间数据类型与基础操作1.1 核心时间对象体系1.2 时间数据生成技巧2. 时间索引与数据

使用SpringBoot整合Sharding Sphere实现数据脱敏的示例

《使用SpringBoot整合ShardingSphere实现数据脱敏的示例》ApacheShardingSphere数据脱敏模块,通过SQL拦截与改写实现敏感信息加密存储,解决手动处理繁琐及系统改... 目录痛点一:痛点二:脱敏配置Quick Start——Spring 显示配置:1.引入依赖2.创建脱敏

Linux链表操作方式

《Linux链表操作方式》:本文主要介绍Linux链表操作方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、链表基础概念与内核链表优势二、内核链表结构与宏解析三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势六、典型应用场景七、调试技巧与