go语言中的反射

138 阅读2分钟

以前用Java开发的时候,尤其是接触到稍微底层一点的东西,比如AOP,动态代理这些东西,都要用到反射,现在学习go语言,发射这些反射和Java里面的及其类似,不过也有差异,以下是一些代码演示

基本数据类型的反射

package main
//反射,基本数据类型
import (
	"fmt"
	"reflect"
)

type myInt int
type Person struct {
	Name string
	Age  int
}

func reflectType(v interface{}) {
	typeOf := reflect.TypeOf(v)
	name := typeOf.Name()
	kind := typeOf.Kind()
	fmt.Printf("【typeof】: %v, 【Name】: %v, 【Kind】: %v\n", typeOf, name, kind)
}
func reflectValue(v interface{}) {
	val := reflect.ValueOf(v)
	kind := val.Kind()
	fmt.Println("原始类型:", kind)
	switch kind {
	case reflect.Int:
		fmt.Println(val.Int())
	case reflect.String:

		fmt.Println(val.String())
	case reflect.Float32:
		fmt.Println(val.Float())
	default:
		fmt.Println("还没有去判断这个类型")
	}
}
func resetValue(v interface{}) {
	val := reflect.ValueOf(v)
	kind := val.Kind()
	//如果传入的参数不是指针类型,那么就不能对其原始的变量进行赋值
	//但是如果传入的参数是指针类型,通过val.Kind()方法获取到的是ptr类型
	//如果想要判断是int,则需要使用val.Elem().Kind()方法
	fmt.Println(kind)
	k := val.Elem().Kind()
	fmt.Println("实际类型:", k)
	if k == reflect.Int64 {
		val.Elem().SetInt(2323)
	} else if k == reflect.String {
		val.Elem().SetString("hello golang")
	} else {
		fmt.Println("暂时没设置这种类型")
	}
}
func main() {
	a := 10
	b := 12.3
	c := true
	d := "nihao"
	var e myInt = 12
	f := Person{
		Name: "nihao",
		Age:  12,
	}
	g := [3]int{0, 1, 2}
	h := []int{4, 5}
	var i = &a

	reflectType(a)
	reflectType(b)
	reflectType(c)
	reflectType(d)
	reflectType(e)
	reflectType(f)
	reflectType(g)
	reflectType(h)
	reflectType(i)
	reflectValue(23)
	reflectValue("string")

	var aint = 12
	resetValue(&aint)
	fmt.Println(aint)

}

结构体的反射

package main

import (
	"fmt"
	"reflect"
)

//反射,结构体

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

func (p Person) GetInfo() string {
	return fmt.Sprintf("Name:%v,Age:%v,Address:%v", p.Name, p.Age, p.Address)
}
func (p *Person) SetInfo(name string, age int, address string) {
	p.Name = name
	p.Age = age
	p.Address = address
}
func main() {
	var p = Person{
		Name:    "silk",
		Age:     20,
		Address: "苏州",
	}
	t := reflect.TypeOf(p)
	if t.Kind() != reflect.Struct && t.Elem().Kind() != reflect.Struct {
		fmt.Println("传入的类型不是结构体")
	}
	field := t.Field(0)
	fmt.Println(field.Name)
	fmt.Println(field.Type)
	fmt.Println(field.Tag.Get("json"))
	name, ok := t.FieldByName("Age")
	if ok {
		fmt.Println(name.Name)
		fmt.Println(name.Type)
		fmt.Println(name.Tag.Get("json"))
	}
	for i := 0; i < t.NumField(); i++ {
		fmt.Printf("name:%v,type:%v,tag:%v\n", t.Field(i).Name, t.Field(i).Type, t.Field(i).Tag.Get("json"))
	}

	method := t.NumMethod()
	fmt.Println("methodcount:", method)
	for i := 0; i < method; i++ {
		fmt.Println(t.Method(i).Name)
	}
	//注意,当使用SetInfo方法时候,传入的必须是指针类型,否则会报错
	val := reflect.ValueOf(&p)
	call := val.MethodByName("GetInfo").Call(nil)
	fmt.Println(call)
	var params []reflect.Value
	params = append(params, reflect.ValueOf("java0904"))
	params = append(params, reflect.ValueOf(23))
	params = append(params, reflect.ValueOf("苏州市工业园区"))
	val.MethodByName("SetInfo").Call(params)
	call = val.MethodByName("GetInfo").Call(nil)
	fmt.Println(call)
	fmt.Println(p)

}

原文链接:www.sdk.cn/details/m1R… SDK社区是一个中立的社区,这里有多样的前端知识,有丰富的api,有爱学习的人工智能开发者,有风趣幽默的开发者带你学python,还有未来火热的鸿蒙,当各种元素组合在一起,让我们一起脑洞大开共同打造专业、好玩、有价值的开发者社区,帮助开发者实现自我价值!