首页 > 其他 > 详细

GO编程(打卡)-Task11: 反射机制

时间:2020-12-22 09:04:25      阅读:25      评论:0      收藏:0      [点我收藏+]

反射机制

是什么

Go 语言提供了一种机制在运行时更新变量和检查它们的值、调用它们的方法,但是在编译时并不知道这些变量的具体类型,这称为反射机制

作用

  • 在编写不定传参类型函数的时候,或传入类型过多时

  • 不确定调用哪个函数,需要根据某些条件来动态执行

实现

Go的反射基础是接口和类型系统,Go的反射机制是通过接口来进行的

Go语言在reflect包里定义各种类型,实现了反射的各种函数,通过它们可以在运行时检测类型的信息、改变类型的值

三定律
1.反射可以将“接口类型变量”转换为“反射类型对象”。
2.反射可以将“反射类型对象”转换为“接口类型变量”。
3.如果要修改“反射类型对象”,其值必须是“可写的”。

package main

import (
	"fmt"
	"reflect"
)

func main() {
	var Num float64 = 3.14
	// 接口类型变量分别转换为反射类型对象v和t
	v := reflect.ValueOf(Num)
	t := reflect.TypeOf(Num)
	fmt.Println("Reflect : Num.Value = ", v)
	fmt.Println("Reflect : Num.Type = ", t)

	// 使用 Interface 方法恢复其接口类型的值
	origin := v.Interface().(float64)
	fmt.Println(origin)

	// 修改“反射类型对象”
	v1 := reflect.ValueOf(Num)
	// v1.SetFloat(6.18)
	fmt.Println("v1的可写性:",v1.CanSet())
}

技术分享图片

小结
1.反射对象包含了接口变量中存储的值以及类型。
2.如果反射对象中包含的值是原始值,那么可以通过反射对象修改原始值;
3.如果反射对象中包含的值不是原始值(反射对象包含的是副本值或指向原始值的地址),则该反射对象不可以修改。

实践

package main

import (
	"fmt"
	"reflect"
)

func hello(){
	fmt.Println("Hello world!")
}

func main() {
	var f float64 = 3.14
	fmt.Println("f的原值:",f)
	p := reflect.ValueOf(&f)
	// reflect.Elem() 方法获取这个指针指向的元素类型。这个获取过程被称为取元素,等效于对指针类型变量做了一个*操作
	v := p.Elem()
	fmt.Println("v的可写性:",v.CanSet())
	v.SetFloat(6.18)
	fmt.Println("f修改后的值:",f)

	// 调用方法
	hl := hello
	fv := reflect.ValueOf(hl)
	fv.Call(nil)
	// 反射会使得代码执行效率较慢,原因有
	// 1.涉及到内存分配以及后续的垃圾回收
	// 2.reflect实现里面有大量的枚举,也就是for循环,比如类型之类的
}

技术分享图片

参考

https://github.com/datawhalechina/go-talent/blob/master/10.反射机制.md

GO编程(打卡)-Task11: 反射机制

原文:https://www.cnblogs.com/rn-05181226-rw/p/14166051.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!