go学习 --- 反射

一、反射

1、反射可以在运行时动态获取变量的各种信息,比如变量的类型(type),类别(kind)

2、如果是结构体变量,还可以获取到结构体本身的信息(包括结构体的字段、方法)

3、通过反射,可以修改变量的值,可以调用关联的方法。

4、使用反射,需要import ("reflect")

二、反射示意图

三、反射的类型转换

变量、interface{} 和reflect.Value是可以相互转换的

 四、使用反射操作基本数据类型

package main

import (
	"fmt"
	"reflect"
)

//定义一个函数
func test(re interface{})  {
	//使用反射获取类型
	rType := reflect.TypeOf(re)
	fmt.Println("rType:",rType)
	//使用反射获取值
	rVal := reflect.ValueOf(re)
	fmt.Println("rVal:",rVal)
	//rVal的值没法直接使用,需要转换
	num := 10 + rVal.Int()
	fmt.Println("num:",num)
    //将rval转化接口
	iV := rVal.Interface()
	//将iV转换为需要的类型
	i := iV.(int)
	num2 := 10+ i
	fmt.Println("num:",num2)
}

func main() {
	//定义一个基本数据类型
	i := 10
	test(i)
}

 

 使用反射操作结构体

package main

import (
	"fmt"
	"reflect"
)
//定义一个结构体
type Student struct {
	Name string
	Age int
}
//定义一个函数
func test01(re interface{})  {
	//使用反射获取类型
	rType := reflect.TypeOf(re)
	fmt.Println("rType:",rType)
	//使用反射获取值
	rVal := reflect.ValueOf(re)
	fmt.Println("rVal:",rVal)
	//这里需要转换
	iV := rVal.Interface()

	student, ok :=iV.(Student)
	if !ok {
		fmt.Println("转换失败")
	}
	fmt.Println(student.Name)
}

func main() {
	student := Student{"小明",20}
	test01(student)
}

五、使用反射修改值

package main

import (
	"fmt"
	"reflect"
)

type Jack struct {
	Name string
}
func main() {
	var a int = 100
	//获取反射对象
	v := reflect.ValueOf(&a)
	//取出地址
	v = v.Elem()
	v.SetInt(1)
	fmt.Println("v的值为",v)
	//修改结构体的值
	jack := &Jack{}
	j := reflect.ValueOf(jack)
	j = j.Elem()
	//获取结构体的字段
	name := j.FieldByName("Name")
	//修改结构体字段的值
	name.SetString("小明")
	fmt.Println("修改后的Name值为:",name.String())
}

 

六、使用反射创建实例

package main

import (
	"fmt"
	"reflect"
)

type Cat struct {
	Name string
}
func main() {
	//使用反射创建实例
	var a int = 10
	v := reflect.TypeOf(a)
	value := reflect.New(v)
	fmt.Println("value的类型为:",value.Type())
	fmt.Println("value的类别为:",value.Kind())
	cat := Cat{
		Name: "小花",
	}
	c := reflect.TypeOf(cat)
	C := reflect.New(c)
	fmt.Println("C的类型为:",C.Type())
	fmt.Println("C的类别为:",C.Kind())
}

 

七、使用反射便利结构体方法

package main

import (
	"fmt"
	"reflect"
)

//定义一个结构体
type Animal struct {
}

func (a Animal) Area() string {
	return "area方法调用"
}
func (a Animal) GetArea()string  {
	return "GetArea方法被调用"
}
func showList(x interface{})  {
	v := reflect.ValueOf(x)
	t := v.Type()
	fmt.Println("t类型为",t)
	for i := 0; i < v.NumMethod(); i++ {
		method := v.Method(i)
		fmt.Println(t.Method(i))
		fmt.Println("方法名为:",t.Method(i).Name)
		fmt.Println(method.String())
	}
}
func main() {
	animal := Animal{}
	showList(animal)

}

 

 八、练习

给你-一个变量var v float64= 1.2,请使用反射来得到它的reflect.Value,然后获取对应的Type, Kind和值,并将reflect.Value转换成interface{} , 再将interface{}转换成float64。

package main

import (
	"fmt"
	"reflect"
)

//
func rtest01(v float64)  {
	//获取ValueOf的值
	rV := reflect.ValueOf(v)
	fmt.Println(rV)
	//获取Kind的值
	i := rV.Kind()
	//获取Type的值
	i2 := rV.Type()
	fmt.Println("i=",i)
	fmt.Println("i2=",i2)
	//转换为接口
	iV := rV.Interface()
	f := iV.(float64)
	fmt.Println(f)

}
func main() {
	var v float64 = 1.2
	rtest01(v)
}


版权声明:本文为qq_46093575原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。