当前位置:网站首页>Go language - reflect
Go language - reflect
2022-06-28 22:51:00 【Crying while learning】
summary
In computer science , Reflection is when a computer program can access 、 The ability to detect and modify its own state or behavior . Reflective reality Java A concept that quickly became popular after its emergence , Rich type information can be obtained through reflection , You can use these types of information to do more flexible work .
It's ok if you don't use reflection , Then we need to use assembly language , Dealing with computer memory . But we often use high-level languages , You need reflection to achieve . Different languages have different mechanisms to implement reflection , And some languages don't support reflection .《Go Language Bible 》 This is how reflection is defined in :
Go Language provides a mechanism to update variables and check their values at run time 、 Call their methods . However, the specific types of these variables are not known at compile time . This is called the reflection mechanism .
What situations require reflection ?
Need to reflect 2 A common scene :
- The type of the parameter passed in by the function cannot be specified , You need to judge the type of the specific parameters passed in at run time .
- Not sure which methods the interface calls , It needs to be determined at run time according to the passed in parameters .
Why not suggest using reflection ?
Reflection is a double-edged sword , Although it's powerful .
- Reflection related code , It is generally difficult to read .
- GO Language as a static language , The compiler can find some type errors in advance during the coding process . But there's nothing you can do with reflection code , So include reflection related code , Errors are often found after running for a period of time . This often leads to serious consequences .
- Reflection has a great impact on performance , One or two orders of magnitude slower than normal code . For operational efficiency , Try to avoid reflection .
How reflection is implemented ?
Go In language we have learned interface, He is Go A very powerful tool for language abstraction . When assigning an entity type to an interface variable , Interfaces store information about entity types . Reflection is achieved by the type information of the interface , Reflection is based on type .
Go Language in reflect Various types are defined in the package , Various functions of reflection are realized . They allow you to detect type information at run time 、 Change the value of the type .
Review two knowledge points :
go Language is a static type language . When the code is compiled , All types have been identified .
interface{}—— Empty interface . An empty interface can represent any type .
Go The reflection of language is based on type .
- Go The variables created by the specified type in the language are called yes Static type , The type is determined when the variable is created .
- Reflection is mainly related to interface{} Type related , It is a specific type , Only interface Type is the reflection .
- Go In language , Variables include (type、value) Two parts ,type It is divided into Static type and concrete type . Every interface Each variable has a corresponding pair,pair Of the actual variables (type、value).interface{} Contains two pointers , A pointer points to type, A pointer points to value. among type It's a specific type .
- If you take a interface{} type , Assign to another interface{}, Then the actual pair Your information will not change . That is, neither the value nor the type will change .
Reflection , In essence, it is used to detect the data stored in interface{} Medium pair A mechanism of .pair Is essentially stored type and value.type and value It is also the two most important types of reflection packages .
Reflection reflect Use
reflect Basic functions of TypeOf and ValueOf
reflect Reflection packages provide two methods ,reflect.TypeOf() and reflect.ValueOf()
- reflect.TypeOf() The type used to dynamically obtain the value in the input parameter interface , If the interface is empty, return nil. It's actually getting interface{} Of pair Medium type.
- reflect.ValueOf() Used to get the value of the data in the input parameter , Return if empty 0. It's actually getting interface{} Of pair Medium value.
All concrete types can be considered as interface{} The concrete implementation of the empty interface .
var x interface{}
var y string
func main() {
x = 11.11
fmt.Println("type x:", reflect.TypeOf(x))
fmt.Println("value x:", reflect.ValueOf(x))
y = "liqi-test"
fmt.Println("type y:", reflect.TypeOf(y))
fmt.Println("value y:", reflect.ValueOf(y))
}
reflect.TypeOf() The type returned is Type,reflect.ValueOf() The type returned is Vlue. about Type and Vlue Next , Contains a large number of methods .
Get structure data by reflection
type Person struct {
Name string
Age int
Sex string
}
func (p Person) Say(msg string) {
fmt.Println("hello,", msg)
}
func (p Person) PrintInfo() {
fmt.Printf(" full name : %s, Age : %d, Gender : %s\n", p.Name, p.Age, p.Sex)
}
func main() {
p1 := Person{"xiaoming", 18, " male "}
getMsg(p1)
}
func getMsg(msg interface{}) {
getType := reflect.TypeOf(msg)
fmt.Println("Type name is:", getType.Name())
fmt.Println("Kind is:", getType.Kind())
getValue := reflect.ValueOf(msg)
fmt.Println("get all Fields:", getValue)
// Get structure fields
fmt.Println("--- Get structure field information ---")
for i := 0; i < getType.NumField(); i++ {
field := getType.Field(i)
fieldValue := getValue.Field(i).Interface()
fmt.Printf(" Structure Field:%v, value :%v, The type of value : %T\n", field.Name, fieldValue, fieldValue)
}
// Access method
fmt.Println("--- Get structure method information ---")
for i := 0; i < getType.NumMethod(); i++ {
getMethod := getType.Method(i)
fmt.Printf(" Method name : %s, Method type : %s\n", getMethod.Name, getMethod.Type)
}
}
Defined a Person Structure , Field has Name、Age、Sex, Two methods of structure are also defined .
- reflect.TypeOf(xx).Name() Gets the name of the type
- reflect.TypeOf(xx).Kind() Get the kind of type
- reflect.TypeOf(xx).NumField() Get the number of structure fields
- reflect.ValueOf(xx).NumField() Get the number of values corresponding to the structure field
- reflect.TypeOf(xx).Field(index) Press the subscript to get the structure field
- reflect.ValueOf(xx).Field(i).Interface() Press the subscript to get the value of the field in the structure ; If not .Interface() The type of result is Vlue type ,interface() The method is equivalent to Vlue The type is cast to the type of the field itself .
- reflect.TypeOf(xx).Method(index) Get the structure method in the following table
- reflect.TypeOf(xx).Method(index).Name() Method name ( The name of the function )
- reflect.TypeOf(xx).Method(index).Type() Type of method ( Function type )
Reflection sets the value of the actual variable
You need to modify the value of the actual variable , through reflect.ValueOf(X) obtain reflect.Value object , Then modify the variable value . But it should be noted that reflect.ValueOf(X) Medium X Must be a pointer object , And then use Elem().Set() Make changes ,Set() The value passed in must be Value type .
func main() {
var num float64 = 11.11
fmt.Println("num The numerical :", num)
numValue := reflect.ValueOf(&num)
fmt.Println("num The type of :", numValue.Elem().Type())
fmt.Println("num Is it possible to modify :", numValue.Elem().CanSet())
SetNum := reflect.ValueOf(22.22)
numValue.Elem().Set(SetNum)
fmt.Println(" After modification num The numerical :", num)
fmt.Println("--- Modify the structure object value ---")
p1 := &Person{"xiaoming", 18, " male "}
fmt.Println(" Structure before modification :", *p1)
personValue := reflect.ValueOf(p1)
fmt.Println(" Whether the structure object can be modified ?:", personValue.Elem().CanSet())
personValue.Elem().FieldByName("Name").SetString("xiaohong")
personValue.Elem().FieldByName("Age").SetInt(20)
personValue.Elem().FieldByName("Sex").SetString(" Woman ")
fmt.Println(" The modified structure :", *p1)
} 
Reflection calls method
type Person struct {
Name string
Age int
Sex string
}
func (p Person) Say(msg string) {
fmt.Println("hello,", msg)
}
func (p Person) PrintInfo() {
fmt.Printf(" full name : %s, Age : %d, Gender : %s\n", p.Name, p.Age, p.Sex)
}
func main() {
p1 := Person{"xiaoming", 18, " male "}
value := reflect.ValueOf(p1)
method1 := value.MethodByName("Say")
method2 := value.MethodByName("PrintInfo")
// Calling method
args1 := []reflect.Value{reflect.ValueOf(" Reflection executes methods with parameters ")}
method1.Call(args1) // With parameters
method2.Call(nil) // No parameter
}
Reflection calls function
Function calls are similar to methods .
func fun1() {
fmt.Println(" Reflection calls nonparametric functions ")
}
func fun2(msg string) {
fmt.Println("hello,", msg)
}
func fun3(i int, s string) (a int, b string) {
a = i + 1
b = s + ", From the function return"
return a, b
}
func main() {
// Reflection calls parameterless functions
funValue1 := reflect.ValueOf(fun1)
if funValue1.Kind() == reflect.Func {
funValue1.Call(nil)
}
// Reflection calls a function with parameters
funValue2 := reflect.ValueOf(fun2)
if funValue2.Kind() == reflect.Func {
funValue2.Call([]reflect.Value{reflect.ValueOf(" Reflection calls parameterized functions ")})
}
// Reflection calls a function that has a return value
funValue3 := reflect.ValueOf(fun3)
if funValue3.Kind() == reflect.Func {
resultValue := funValue3.Call([]reflect.Value{reflect.ValueOf(10), reflect.ValueOf(" Function has return value ")})
fmt.Println(" The return value of a function with a return value :", resultValue[0].Interface(), resultValue[1].Interface())
}
}
边栏推荐
- Gross vs60 billion. Is food safety the biggest obstacle to Weilong's listing?
- 穿越过后,她说多元宇宙真的存在
- 长投学堂帮忙开证券账户是安全靠谱的吗?个人如何开
- Zadig + sonarqube, ensuring the safety of the development process
- Online text filter less than specified length tool
- 【Try to Hack】nmap
- 利用Redis实现点赞功能的示例代码
- Zadig + SonarQube,为开发过程安全保驾
- Huawei cloud gaussdb (for redis) unveiling issue 19: inventory of six second level capabilities
- 复杂嵌套的对象池(4)——管理多类实例和多阶段实例的对象池
猜你喜欢

PyTorch搭建Transformer实现多变量多步长时间序列预测(负荷预测)

On the necessity and solution of building a campus online teaching video convergence platform

Windows mysql5.7 enable binlog log

宜明昂科在港交所递表:2021年亏损翻倍,过往融资额存在夸大情形

Panxiaoming, senior vice president of IC nansha|amd and President of Greater China: process, architecture and platform optimization break through the computing boundary

Lecun predicts AgI: big model and reinforcement learning are both ramps! My world model is the new way

强大的开源API接口可视化管理平台-YApi

The example application of histogram in data visualization makes the public performance results clear at a glance

超级工厂里的生意图鉴

This simple little function saves 213 hours for our production research team in half a year
随机推荐
[deep learning] (3) encoder mechanism in transformer, complete pytoch code attached
Wave picking of WMS warehouse management system module
JS array common methods
计数排序的简单理解
In order to control the risks, how to choose a franchise company?
After crossing, she said that the multiverse really exists
带链接跳转的微信红包封面制作教程和使用指南
在产业互联网时代,传统意义上的互联网将会演变出来诸多新的形态
【Try to Hack】nmap
Production environment sonarqube installation
Code example of hiredis
【kotlin】好看的弹出框、自定义弹出框(对话框)、扩展函数、菊花等待条、消息提示框
Career consultation | in the data analysis interview, it is only reliable to introduce yourself in this way
Qsrand, srand random number generating function in qt5.15 has been discarded
[kotlin] beautiful pop-up box, custom pop-up box (dialog box), extension function, chrysanthemum waiting bar, message prompt box
网上办理股票开户安全性高吗?
时间序列预测系列文章总结(代码使用方法)
On the necessity and solution of building a campus online teaching video convergence platform
爱数SMART 2022峰会开启,分享数据战略与建设数据驱动型组织方法论
flowable 边界定时器