《Go语言从入门到精通》Go语言的反射机制_第1页
《Go语言从入门到精通》Go语言的反射机制_第2页
《Go语言从入门到精通》Go语言的反射机制_第3页
《Go语言从入门到精通》Go语言的反射机制_第4页
《Go语言从入门到精通》Go语言的反射机制_第5页
已阅读5页,还剩32页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

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. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论