go 反射

go 反射

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

import (“reflect”)

  • reflect.TypeOf,获取变量的类型,返回reflect.Type类型
  • reflect.ValueOf,获取变量的值,返回reflect.Value类型
  • reflect.Value.Kind,获取变量的类别,返回一个常量
  • reflect.Value.Interface(),转换成interface{}类型

package main

import (
	"fmt"
	"reflect"
)

type Student struct {
	Name  string
	Age   int
	Score float32
}

func test(b interface{}) {
	t := reflect.TypeOf(b)
	fmt.Println(t)

	v := reflect.ValueOf(b)
	k := v.Kind()
	fmt.Println(k)

	iv := v.Interface()
	stu, ok := iv.(Student)
	if ok {
		fmt.Printf("%v %T\n", stu, stu)
	}
}

func testInt(b interface{}) {
	val := reflect.ValueOf(b)

	val.Elem().SetInt(100)

	c := val.Elem().Int()
	fmt.Printf("get value  interface{} %d\n", c)
	fmt.Printf("string val:%d\n", val.Elem().Int())

}

func main() {
	var a Student = Student{
		Name:  "stu01",
		Age:   18,
		Score: 92,
	}
	test(a)

	var b int = 1
	b = 200
	testInt(&b)
	fmt.Println(b)

}

 

获取变量的值

  • reflect.ValueOf(x).Float() 
  • reflect.ValueOf(x).Int()
  • reflect.ValueOf(x).String()
  • reflect.ValueOf(x).Bool()

改变变量的值

  • reflect.Value.SetXX相关方法
  • reflect.Value.SetFloat(),设置浮点数
  • reflect.Value.SetInt(),设置整数
  • reflect.Value.SetString(),设置字符串

用反射操作结构体

  • reflect.Value.NumField()获取结构体中字段的个数
  • reflect.Value.Method(n).Call来调用结构体中的方法
package main

import (
	"fmt"
	"reflect"
)

type NotknownType struct {
	s1 string
	s2 string
	s3 string
}
func (n NotknownType) String() string {
	return n.s1 + "-" + n.s2 + "-" + n.s3
}
var secret interface{} = NotknownType{"Ada", "Go", "Oberon"}

func main() {
	value := reflect.ValueOf(secret) // <main.NotknownType Value>
	typ := reflect.TypeOf(secret)    // main.NotknownType
	fmt.Println(typ)

	knd := value.Kind() // struct
	fmt.Println(knd)

	for i := 0; i < value.NumField(); i++ {
		fmt.Printf("Field %d: %v\n", i, value.Field(i))
		//value.Field(i).SetString("C#")
	}

	results := value.Method(0).Call(nil)
	fmt.Println(results) // [Ada - Go - Oberon]
}

 

posted @ 2017-09-05 11:24  shhnwangjian  阅读(207)  评论(0编辑  收藏  举报