版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
Go语言的反射机制Go语言从入门到精通了解反射机制了解一些Go语言中反射的应用01REFLECT02DATATYPE03APPLICATIONtarget目标掌握Go语言中用反射机制获取数据类型的方法反射机制在程序运行时动态地获取内部数据、改变内部数据和程序行为的能力目录导航16.1用反射机制获取基本类型的信息Contentsreflect包b
:=
'a't.Printfln("b的类型是
%v",
reflect.TypeOf(b))
c
:=
64t.Printfln("c的类型是
%v",
reflect.TypeOf(c))
f
:=
50.0t.Printfln("f的类型是
%v",
reflect.TypeOf(f))
s
:=
"这是一个字符串"t.Printfln("s的类型是
%s",
reflect.TypeOf(s).String())
获取基本数据的类型b的类型是int32c的类型是intf的类型是float64s的类型是stringreflect.TypeOf函数的定义func
TypeOf(i
interface{})
Type目录导航16.2用反射获取复杂类型的信息Contents数组、映射与简单自定义类型的反射intArray的类型是[5]intintSlice的类型是[]float32stringMap的类型是map[string]stringc的类型是main.NewIntd的类型是int32type
NewInt
int32type
IntAlias
=
int32
func
main()
{intArray
:=
[5]int{3,
5,
8,
10,
99}t.Printfln("intArray的类型是
%v",
reflect.TypeOf(intArray))
floatSlice
:=
make([]float32,
10)t.Printfln("intSlice的类型是
%v",
reflect.TypeOf(floatSlice))
stringMap
:=
make(map[string]string,
10)t.Printfln("stringMap的类型是
%v",
reflect.TypeOf(stringMap))
c
:=
NewInt(32)t.Printfln("c的类型是
%v",
reflect.TypeOf(c))
var
d
IntAlias
=
32t.Printfln("d的类型是
%v",
reflect.TypeOf(d))自定义结构的反射type
NewStruct
struct
{
X
int
Y
int
Z
int}
func
main()
{point
:=
NewStruct{X:
10,
Y:
20,
Z:
50}t.Printfln("point的类型是
%v",
reflect.TypeOf(point))
pointP
:=
&NewStruct{X:
10,
Y:
20,
Z:
50}t.Printfln("pointP的类型是
%v",
reflect.TypeOf(pointP))}point的类型是main.NewStructpointP的类型是*main.NewStruct目录导航16.3函数的传值与传引用Contents传值与传引用(指针)的对比func
setv(numberA
int)
{
numberA
=
99}
func
setp(numberA
*int)
{
*numberA
=
10}
func
main()
{
var
c
int
=
99
t.Printfln("c:
%v",
c)
setv(c)
t.Printfln("c:
%v",
c)
setp(&c)
t.Printfln("c:
%v",
c)
运行结果分析c:99c:99c:10对象中绑定值与引用的成员函数对比type
NewStruct
struct
{
X
int
Y
int
Z
int}
func
(v
NewStruct)
Sum()
int
{
return
v.X
+
v.Y
+
v.Z}
func
(p
*NewStruct)
Set(xA,
yA,
zA
int)
{
p.X
=
xA
p.Y
=
yA
p.Z
=
zA}目录导航16.4用反射获取结构类型(对象)的成员信息Contents对象类定义type
NewStruct
struct
{
X
int
Y
int
Z
int}
func
(v
NewStruct)
Sum()
int
{
return
v.X
+
v.Y
+
v.Z}
func
(p
*NewStruct)
Set(xA,
yA,
zA
int)
{
p.X
=
xA
p.Y
=
yA
p.Z
=
zA}
func
(v
NewStruct)
String()
string
{
return
fmt.Sprintf("[X:
%v,
Y:
%v,
Z:
%v]",
v.X,
v.Y,
v.Z)}获取成员变量的信息pointT
:=
NewStruct{X:
10,
Y:
20,
Z:
50}
typeT
:=
reflect.TypeOf(pointT)
t.Printfln("pointT的类型是:%v,类型名称(没有前缀)是:%v",
typeT,
typeT.Name())
fieldCountT
:=
typeT.NumField()
t.Printfln("%v类型的字段数量为:%v",
typeT.Name(),
fieldCountT)
for
i
:=
0;
i
<
fieldCountT;
i++
{
fieldT
:=
typeT.Field(i)
t.Printfln("第%v个字段名称为%v,类型为%v",
i+1,
fieldT.Name,
fieldT.Type)}结果分析pointT的类型是:main.NewStruct,类型名称(没有前缀)是:NewStructNewStruct类型的字段数量为:3第1个字段名称为X,类型为int第2个字段名称为Y,类型为int第3个字段名称为Z,类型为int获取成员函数的信息methodCountT
:=
typeT.NumMethod()
t.Printfln("%v类型的方法数量为:%v",
typeT.Name(),
methodCountT)
for
i
:=
0;
i
<
methodCountT;
i++
{
methodT
:=
typeT.Method(i)
t.Printfln("第%v个方法名称为%v,
定义为:%v",
i+1,
methodT.Name,
methodT.Type)}
type2T
:=
reflect.TypeOf(&pointT)
methodCount2T
:=
type2T.NumMethod()
t.Printfln("%v类型的方法数量为:%v",
type2T,
methodCount2T)
for
i
:=
0;
i
<
methodCount2T;
i++
{
method2T
:=
type2T.Method(i)
t.Printfln("第%v个方法名称为%v,
定义为:%v",
i+1,
method2T.Name,
method2T.Type)}结果分析NewStruct类型的方法数量为:2第1个方法名称为String,定义为:func(main.NewStruct)string第2个方法名称为Sum,定义为:func(main.NewStruct)int*main.NewStruct类型的方法数量为:3第1个方法名称为Set,定义为:func(*main.NewStruct,int,int,int)第2个方法名称为String,定义为:func(*main.NewStruct)string第3个方法名称为Sum,定义为:func(*main.NewStruct)int目录导航16.5用反射获取空接口类型数据的实际类型Contents函数通过反射解析interface{}类型的参数func
NumberToStringByReflect(valueA
interface{})
string
{
typeT
:=
reflect.TypeOf(valueA)
valueT
:=
reflect.ValueOf(valueA)
t.Printfln("%v,
%v",
typeT,
valueT)
switch
typeT.Name()
{
case
"bool":
return
valueT.String()
default:
return
valueT.String()
}}
func
main()
{
t.Printfln("%v",
NumberToStringByReflect(false))}目录导航16.6用Kind函数获取基类型Contents获取和比对基类型type
NewInt
int32type
MyInt
=
int32
func
check(valueA
interface{})
{
typeT
:=
reflect.TypeOf(valueA)
valueT
:=
reflect.ValueOf(valueA)
t.Printfln("类型:%v,
基类型:%v",
typeT,
typeT.Kind())
t.Printfln("实际数值:%v,基类型:%v",
valueT,
valueT.Kind())}
func
main()
{
check(NewInt(16))
check(MyInt(78))
check(byte(9))
if
reflect.TypeOf(NewInt(8)).Kind()
==
reflect.TypeOf(MyInt(10)).Kind()
{
t.Printfln("NewInt(8)与MyInt(10)的基类型相同,都是%v",
reflect.TypeOf(MyInt(10)).Kind().String())
}
else
{
t.Printfln("NewInt(8)与MyInt(10)的基类型不同")
}}结果分析类型:main.NewInt,基类型:int32实际数值:16,基类型:int32类型:int32,基类型:int32实际数值:78,基类型:int32类型:uint8,基类型:uint8实际数值:9,基类型:uint8NewInt(8)与MyInt(10)的基类型相同,都是int32基类型列表InvalidBoolIntInt8Int16Int32
Int64UintUint8(byte)Uint16Uint32(rune)Uint64
Uintptr
Float32Float64Complex64Complex128ArrayChanFuncInterfaceMapPtrSliceStringStructUnsafePointer目录导航16.7判断对象是否实现了某方法或接口Contents判断对象是否实现了某成员函数或接口func
check(valueA
interface{})
{
typeT
:=
reflect.TypeOf(valueA)
valueT
:=
reflect.ValueOf(valueA)
t.Printfln("类型:%v,基类型:%v,实际数值:%v",
typeT,
valueT.Kind(),
valueT)
if
valueT.Kind()
==
reflect.Struct
||
valueT.Kind()
==
reflect.Ptr
{
methodT
:=
valueT.MethodByName("SumWith")
if
methodT.IsValid()
{
t.Printfln("类型:%v
包含
SumWith方法",
typeT)
}
}
interfaceTypeT
:=
reflect.TypeOf((*MySum)(nil)).Elem()
t.Printfln("interfaceTypeT:
%v",
interfaceTypeT)
if
typeT.Implements(interfaceTypeT)
{
t.Printfln("类型:%v
实现了接口
MySum",
typeT)……目录导航16.8动态调用对象的方法Contents动态调用对象的方法(成员函数)methodT
:=
valueT.MethodByName("Sum")
if
methodT.IsValid()
{
resultT
:=
methodT.Call(nil)
t.Printfln("函数调用结果:%#v",
resultT[0].Float())}目录导航16.9修改数据Contents判断是否可修改并修改对象的数据if
valueT.Kind()
==
reflect.Ptr
{
valueT
=
valueT.Elem()}
if
valueT.CanSet()
{
if
valueT.Kind()
==
reflect.Struct
{
fieldCountT
:=
valueT.NumField()
for
i
:=
0;
i
<
fieldCountT;
i++
{
fieldValueT
:=
valueT.Field(i)
if
fieldValueT.CanSet()
{
if
fieldValueT.Kind()
==
reflect.Int
{
fieldValueT.SetInt(fieldValueT.Int()
+
100)
}
else
if
fieldValueT.Kind()
==
reflect.Float64
{
fieldValueT.SetFloat(fieldValueT.Float()
+
200.5)
}
}
}
}}目录导航16.10实例:JSON处理Contents场景说明任意一段JSON文本,可能表示的是任意复杂的类型
其中可能会有多级的嵌套结构,例如字典中包含数组,数组中又包含字典等
需要反射机制来根据具体的数据类型来逐级进行处理分析JSON文本var
jsonTextG
=
`{"ID":
"12345","name":
"张三","曾用名":
["李四",
"王五"],"年龄":
28,"电话":
{"座机":
"66668888",
"手机":
},"pets":
[
{"name":
"Tom",
"type":
"cat"},
{"name":
"Jerry",
"type":
"mouse"}
]}`关键代码:分析JSON对象func
analyzeJsonObject(vA
interface{},
compareKeyA
string,
lastKeyA
string,
listA
*[]string)
{
valueT
:=
reflect.ValueOf(vA)
switch
valueT.Kind()
{
case
reflect.String:
if
compareKeyA
!=
""
{
if
lastKeyA
!=
compareKeyA
{
break
}
}
*listA
=
append(*listA,
valueT.String())
case
reflect.Slice:
for
i
:=
0;
i
<
valueT.Len();
i++
{
v
:=
valueT.Index(i)
analyzeJsonObject(v.Interface(),
compareKeyA,
"",
listA)
}
case
reflect.Map:
keys
:=
valueT.MapKeys()
for
_,
k
:=
range
keys
{
v
:=
valueT.MapIndex(k)
analyzeJsonObject(v.Interface(),
compa
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 玻璃制品进出口协议
- 航空业采购经理面试题集
- 汽车行业数据分析专业面试题库及答题指南
- IT专员助理面试题及答案
- 百度AI算法技术面试问题解析
- 医生职业面试攻略与问题解析
- 2025年中国铁路兰州局集团有限公司招聘普通高校毕业生468人备考题库(一)及完整答案详解一套
- 2025年宁波市轨道交通物产置业有限公司下属项目公司社会招聘备考题库及一套答案详解
- 中国电信售前经理产品知识竞赛题库含答案
- 现场TPM工程师面试题集
- 施工升降机防护方案
- 温室大棚可行性报告修改版
- JISG3141-2017冷轧钢板及钢带
- 瑞加诺生注射液-药品临床应用解读
- 2025中医体重管理临床指南
- xx区老旧街区改造项目可行性研究报告
- 《新闻基础知识》近年考试真题题库(附答案)
- 人教版高中生物必修1全册新编教案版本
- 手卫生依从性PDCA的循环管理课件
- 中铁四局集团工程项目精细化管理手册修订稿
- 中国法律史-第一次平时作业-国开-参考资料
评论
0/150
提交评论