反射
func main() {
var a int = 5
//通过反射可以获取一个变量的类型和数值
value := reflect.ValueOf(a) //返回类型为reflect.Value的变量
typeof := reflect.TypeOf(a) //返回类型为reflect.Type的变量
fmt.Println(value, typeof) //5 int
//根据反射的值,来获取value的种类和值,
fmt.Println(value.Kind()) //int kind()反射对象才可以用
fmt.Println(value.Type()) //int
fmt.Println(value.Int()) //只能写本来的类型,写float会报错
fmt.Println(reflect.Int) //int 是reflect下的常量
fmt.Println(value.Kind() == reflect.Int) //true
fmt.Println(value.Kind(), value.Type(), reflect.TypeOf(value)) //int int reflect.Value
fmt.Printf("%T,%T,%T", value.Kind(), value.Type(), reflect.TypeOf(value)) //int int reflect.Value
}
反射获取变量信息
反射获取不到私有信息。所以开头要大写
type User struct {
Name string
Age int
Sex string
}
func (user User) GetName() {
fmt.Println("name", user.Name)
}
func (user User) GetAge() {
fmt.Println("age", user.Age)
}
// main函数测试
func main() {
user := User{"ys", 18, "男"}
reflectGetInfo(user)
}
// 反射获取函数结构体信息
func reflectGetInfo(user interface{}) {
//获取参数的类型,先reflect.typeof()获取到反射对象reflect.Type,操作这个对象
typeOf := reflect.TypeOf(user)
fmt.Println(typeOf.Kind()) //获取种类 struct
fmt.Println(typeOf.Name()) //获取类名 User
//获取值
value := reflect.ValueOf(user)
fmt.Println(value) //{ys 8 男}
/*
1、先获取Type对象,reflect.Type
NumField()获取有几个字段
Field(index)得到字段的值
2、通过Filed()获取每一个Filed字段
3、字段大写就Interface(),得到对应的Value,小写字段不需要
*/
for i := 0; i < typeOf.NumField(); i++ {
fieldType := typeOf.Field(i) //获取字段对象
valueType := value.Field(i).Interface() //获取字段的值
fmt.Printf("字段类型:%s,字段名称:%s,字段值:%v\n", fieldType.Type, fieldType.Name, valueType)
}
fmt.Println(typeOf.NumMethod())
for i := 0; i < typeOf.NumMethod(); i++ {
method := typeOf.Method(i)
fmt.Printf("方法名:%s,方法类型:%v\n", method.Name, method.Type)
}
}
反射设置变量的值
1.ValueOf()里写&,返回一个指针
2.指针.Elem,返回的对象,有CanSet权限可以操作变量
3.通过SetInt方法去改变。(Int是变量的类型,注意自行判断)
func main() {
user := pojo.User{"ys", 15, "男"}
value := reflect.ValueOf(&user) //取出来指针
fmt.Println(user)
if value.Kind() == reflect.Pointer { //判断是不是reflect.Pointer类型
newValue := value.Elem()
if newValue.CanSet() { //判断是不是可以改变值
newValue.FieldByName("Name").SetString("zs") //.字段名.Set类型 改变
newValue.FieldByName("Age").SetInt(15)
}
}
fmt.Println(user)
}
反射调用方法
func main() {
user := pojo.User{"ys", 15, "男"}
value := reflect.ValueOf(user)
//无参方法调用,可以传nil
value.MethodByName("GetName").Call(nil)
//有参方法调用,要先准备[]reflect.Value切片
args := make([]reflect.Value, 1)
args[0] = reflect.ValueOf(123) //赋值的类型也是reflect.Value类型
value.MethodByName("GetAge").Call(args)
}
反射调用函数
func main() {
fun1 := reflect.ValueOf(fun1)
//执行方法1
fun1.Call(nil) //无参
//有参的需要反射类型value切片
args1 := make([]reflect.Value, 2)
args1[0] = reflect.ValueOf(5)
args1[1] = reflect.ValueOf("hh")
//执行方法2
reflect.ValueOf(fun2).Call(args1) //有参
//执行方法3
result := reflect.ValueOf(fun3).Call(args1) //返回的是一个切片类型
fmt.Println(result[0].Interface()) //反射里切片取值也要用.Interface
}
func fun1() {
fmt.Println("fun1:无参")
}
func fun2(i int, s string) {
fmt.Println("fun2:有参", i, s)
}
func fun3(i int, s string) string {
fmt.Println("fun3:有参有返回", i, s)
return s
}