Go之reflect标准库

反射能让我们更简便地获得一个对象的类型、值,如果对象是结构体还能获得它的属性、方法。

type Type interface {
    Align() int
    FieldAlign() int
    Method(int) Method
    MethodByName(string) (Method, bool)
    NumMethod() int
    Name() string
    PkgPath() string
    Size() uintptr
    String() string
    Kind() Kind
    Implements(u Type) bool
    AssignableTo(u Type) bool
    ConvertibleTo(u Type) bool
    Comparable() bool
    Bits() int
    ChanDir() ChanDir
    IsVariadic() bool
    Elem() Type
    Field(i int) StructField
    FieldByIndex(index []int) StructField
    FieldByName(name string) (StructField, bool)
    FieldByNameFunc(match func(string) bool) (StructField, bool)
    In(i int) Type
    Key() Type
    Len() int
    NumField() int
    NumIn() int
    NumOut() int
    Out(i int) Type
    common() *rtype
    uncommon() *uncommonType
}

type Value struct {
    typ *rtype
    ptr unsafe.Pointer
    flag
}

下文再介绍 reflect.Value 常用方法。

 

1、ValueOf () 从接口变量到反射对象

函数:

func TypeOf(i interface{}) Type

func ValueOf(i interface{}) Value

例子:

	var age interface{} = 20
	fmt.Println("age: ", age)

	// 1、TypeOf ValueOf 从接口变量到反射对象
	t := reflect.TypeOf(age)
	v := reflect.ValueOf(age)
	fmt.Printf("TypeOf %T \n", t)
	fmt.Printf("ValueOf %T \n", v)
	// TypeOf *reflect.rtype
	// ValueOf reflect.Value

 

2、Interface() 从反射对象到接口变量

函数:

func (v Value) Interface() (i interface{})

例子:

	// 2、Interface 从反射对象到接口变量
	v = reflect.ValueOf(age)
	i := v.Interface()
	fmt.Printf("Interface %T %v\n", i, i)
	// Interface int 20

最后转换后的对象,静态类型为 interface{} ,如果要转成最初的原始类型,需要再类型断言转换一下

i := v.Interface().(int)

 

3、Elem() 获取指针指向的数据(用来修改反射数据)

函数:

func (v Value) Elem() Value

例子:

	// 3、Elem 获取指针指向的数据(用来修改反射数据)
	v1 := reflect.ValueOf(&age)
	fmt.Println("v1 可写性为:", v1.CanSet())
	v2 := v1.Elem()
	fmt.Println("v2 可写性为:", v2.CanSet())
	// v1 可写性为: false
	// v2 可写性为: true

由于go语言函数是值传递,所以想要修改值必须得传入指针变量。

 

4、SetString() 设置值

函数:

func (v Value) SetString(x string)

例子:

	// 4、SetString() 设置值
	name := "hello"
	v1 = reflect.ValueOf(&name)
	v2 = v1.Elem()
	v2.SetString("world")
	fmt.Printf("SetString %T %v\n", name, name)
	// SetString string world

 

5、Kind() 获取类别(相对Type 更广义)

函数:

func (v Value) Kind() Kind

例子:

	// 5、Kind() 获取类别(相对Type 更广义)
	m := People{}
	t = reflect.TypeOf(m)
	fmt.Printf("Type: %v\n",t)
	fmt.Printf("Kind: %v\n",t.Kind())
	// Type: main.People
	// Kind: struct

 

6、Int()、Float()、String()、Bool()、Interface() 类型转换

函数:

func (v Value) Int() int64

例子:

	// 6、Int()、Float()、String()、Bool()、Interface() 类型转换
	age = 88
	ageV := reflect.ValueOf(age)
	fmt.Printf("Int 转换前, type: %T, value: %v \n", ageV, ageV)
	ageV2 := ageV.Int()
	fmt.Printf("Int 转换后, type: %T, value: %v \n", ageV2, ageV2)
	// Int 转换前, type: reflect.Value, value: 88
	// Int 转换后, type: int64, value: 88

 

7、NumField() 获取结构体属性个数

函数:

func (v Value) NumField() int

例子:

	// 7、NumField() 获取结构体属性个数
	p := People{name: "hss", age: 27}
	pv := reflect.ValueOf(p)
	fmt.Printf("NumField: %v\n", pv.NumField())
	// NumField: 2

 

8、Field() 获取结构体属性

函数:

func (v Value) Field(i int) Value

例子:

	// 8、Field() 获取结构体属性
	p = People{name: "hss", age: 27}
	pv = reflect.ValueOf(p)
	fmt.Printf("Field 1: %v\n", pv.Field(0))
	fmt.Printf("Field 2: %v\n", pv.Field(1))
	// Field 1: hss
	// Field 2: 27

 

9、NumMethod() 获取结构体方法个数

函数:

func (v Value) NumMethod() int

例子:

	// 9、NumMethod() 获取结构体方法个数
	p = People{name: "hss", age: 27}
	pv = reflect.ValueOf(p)
	fmt.Printf("NumMethod: %v\n", pv.NumMethod())
	// NumMethod: 2

 

10、Method() 获取结构体方法

函数:

func (v Value) Method(i int) Value

例子:

	// 10、Method() 获取结构体方法
	p = People{name: "hss", age: 27}
	tp := reflect.TypeOf(p)
	fmt.Printf("Method 1: %v\n", tp.Method(0).Name)
	fmt.Printf("Method 2: %v\n", tp.Method(1).Name)
	// Method 1: SayBye
	// Method 2: SayHello

 

优点:

1、避免硬编码

2、某种情况下 方便辅助一些类型判断

3、某种情况下 方便辅助根据对象获取属性和方法

 

缺点:

1、有点抽象难理解

2、学习成本高可读性差

3、运行效率低、性能不佳

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值