Go_反射

反射 : 在运行时动态获取变量相关信息

reflect包

reflect.TypeOf 获取变量的类型, 返回reflect.Type类型
func TypeOf(i interface{}) Type{}

reflect.ValueOf, 获取变量的值, 返回reflect.Value类型
func ValueOf(i interface{}) Value {}

reflect.Value.King, 获取变量类别, 返回一个常量
func (v Value) Kind() Kind {}

reflect.Value.Interface(), 转化成interface{}类型
func (v Value) Interface() (i interface{}) {}

测试

package main

import (
    "fmt"
    "reflect"
)

func test(b interface{}){
    t:= reflect.TypeOf(b)
    fmt.Println(t) // int 能得到具体的类型
    
    v := reflect.ValueOf(b) // Value类型有许多的方法, Value.Kind() 获得类别
    
    kd := v.Kind()
    if kd != reflect.Struct{
        fmt.Println("这不是个结构体")
      // reflect.Struct是一个常量, 可以通过kd和他来判断传进来的是不是结构体, 还有其他类型
    }
}

func main(){
    var a int = 200
    test(a)
}    

Value取值修改

func test(b interface{}){
    t:= reflect.TypeOf(b)
    fmt.Println(t) // int 能得到具体的类型
    
    v := reflect.ValueOf(b) // Value类型有许多的方法, Value.Kind() 获得类别
    v.Int() // 取值, 对应类型
    v.Elem().Int() // 指针取值, 对应类型
    v.SetInt(100) // 非指针修改, 对应类型
    v.Elem().SetInt(100) // 指针修改, 对应类型
}

操作字段与方法

根据名称获取

package main

import (
    "fmt"
    "reflect"
)

type Student struct{
	name string
	age int
}

func (stu Student) Run(){
	fmt.Println("跑起来吧")
}


func test(b interface{}){
    t:= reflect.TypeOf(b)
    fmt.Println(t) // int 能得到具体的类型
    
	val := reflect.ValueOf(b) // Value类型有许多的方法, Value.Kind() 获得leibie
	fmt.Println(val.FieldByName("name").String())
	val.MethodByName("Run").Call(nil)
}

func main(){
	var a Student
	a = Student{"王二小", 18}
    test(a)
}

循环获取

字段

package main

import (
    "fmt"
    "reflect"
)

type AA struct{
	name string
	age int
}

func test(b interface{}){
    t:= reflect.TypeOf(b)
    fmt.Println(t) // int 能得到具体的类型
    
    val := reflect.ValueOf(b) // Value类型有许多的方法, Value.Kind() 获得类别

	for i:=0;i<val.NumField();i++{ // 获取类型的字段数量, 
		if val.Field(i).Kind() == reflect.Int{ // 取到字段并且判断类别
			fmt.Println(val.Field(i).Int())
		}  // 得到的也是Value对象
	}
}

func main(){
	var a AA
	a = AA{"王二小", 18}
    test(a)
}

方法

package main

import (
    "fmt"
    "reflect"
)

type Student struct{
	name string
	age int
}

func (stu Student) Run(){
	fmt.Println("跑起来吧")
}


func test(b interface{}){
    t:= reflect.TypeOf(b)
    fmt.Println(t) // int 能得到具体的类型
    
    val := reflect.ValueOf(b) // Value类型有许多的方法, Value.Kind() 获得leibie
	fmt.Println(val.NumMethod())
	for i:=0;i<val.NumMethod();i++{

		fmt.Println(val.Method(i).Call(nil))  // 拿到函数并调用
	}
}

func main(){
	var a Student
	a = Student{"王二小", 18}
    test(a)
}

通过反射访问Tag

package main

import (
    "fmt"
    "reflect"
)

type Student struct{
	Name string `json:"name"`
	Age int `json:"age"`
}

func (stu Student) Run(){
	fmt.Println("跑起来吧")
}


func test(b interface{}){ 
	val := reflect.TypeOf(b) 
	// val.Elem().FieldByName("Name").Tag.Get("json")
	fmt.Println(val.Field(1).Tag.Get("json")) // 获取字段Tag的json内容, 可以用FieldByName,不过他有俩返回值
}

func main(){
	var a Student
	a = Student{"王二小", 18}
    test(a)
}

  

  

 

posted @ 2018-09-11 10:46  瓜田月夜  阅读(89)  评论(0编辑  收藏  举报