Go 反射学习笔记

反射


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
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

tigeraowu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值