Go之路(十九):反射

反射

反射主要是可以动态获取变量以及可以对变量进行很多操作

例子:

package main

import(
	"fmt"
	"reflect"
)

type Student struct{
	Name string
	Age int
}

func test1(a interface{}){
	// 把a转换成reflect.value类型,可以有许多操作
	fmt.Println(reflect.TypeOf(a))
	v := reflect.ValueOf(a)
	fmt.Println(reflect.TypeOf(v))
	fmt.Println(v)
	k := v.Kind()
	fmt.Println(k)
	t := v.Type()
	fmt.Println(t)
	
}

func main()  {
	var a = Student{
		Name:"tom",
		Age : 13,
	}
	test1(a)
}

  另外,当传入指针进入的时候,需要用a.Elem()来获取变量的值,如果不这样做 会报错

例如:

package main

import(
	"fmt"
	"reflect"
)

type Student struct{
	Name string
	Age int
}

func test1(a interface{}){
	

	v := reflect.ValueOf(a)
	v.SetInt(100)
}

func main()  {
	var a int = 100
	test1(a)
	fmt.Println(a)
}

  结果:

 

传入指针时,需要加上Elem()方法才能获取到指针所指的变量(因为反射的这些类型不支持*号操作)

package main

import(
	"fmt"
	"reflect"
)

type Student struct{
	Name string
	Age int
}

func test1(a interface{}){
	

	v := reflect.ValueOf(a)
	v.Elem().SetInt(100)
}

func main()  {
	var a int = 100
	test1(&a)
	fmt.Println(a)
}

  另外,还可以对值的方法,字段等进行操作

但是如果结构体内的方法名称是小写的话是获取不到的

package main

import(
	"fmt"
	"reflect"
)

type Student struct{
	Name string
	Age int
}

func (self Student)Test(){
	fmt.Println("i am the test")
}

func (self Student)Test2(){
	fmt.Println("i am the test")
}


func test1(a interface{}){
	
	v := reflect.ValueOf(a)
	kd := v.Kind()
	fmt.Println(kd)
	if kd != reflect.Struct{
		fmt.Println("请传入正确的类型")
	}
	fileds := v.NumField()
	fmt.Println(fileds)
	methods := v.NumMethod()
	fmt.Println(methods)
	for i:=0;i<fileds;i++{
		fmt.Println(v.Field(i))
	}
}

func main()  {
	var a = Student{
		Name:"tom",
		Age:12,
	}
	test1(a)
	fmt.Println(a)
}

  

 

posted @ 2018-12-05 21:17  __Miracle  阅读(115)  评论(0编辑  收藏  举报