当前位置:网站首页>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())
}
}
边栏推荐
- Online text filter less than specified length tool
- What is low code development?
- Heavyweight! CDA certification test preparation Q & A Online
- What is the prospect of VR panoramic production?
- Post-00 cloud native Engineer: use Zadig to increase revenue and reduce expenditure for the R & D of Sichuang Technology (Guangzhou public transport)
- How powerful is the Zadig build? Practice together
- Zadig 面向開發者的自測聯調子環境技術方案詳解
- How to use the apipost script - global variables
- Zadig + 洞态 IAST:让安全溶于持续交付
- Qt5.15中qsrand,srand随机数生成函数已弃用问题
猜你喜欢

00 後雲原生工程師:用 Zadig 為思創科技(廣州公交)研發開源節流

Description détaillée du schéma technique du sous - environnement syntonique auto - test de Zadig pour les développeurs

Progress of dbnn experiment

C#/VB.NET 将PDF转为Excel

Yiming Anke submitted a statement to the Hong Kong Stock Exchange: the loss doubled in 2021, and the past financing amount was exaggerated

flowable 边界定时器

How to solve the problem of desktop without sound

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

Online text filter less than specified length tool

一文读懂,WMS仓储管理系统与ERP有什么区别
随机推荐
torch. nn. Transformer import failed
网上办理股票开户安全性高吗?
题解 洛谷P1762 偶数/6.21校内考试T2
深入虚拟内存(Virtual Memory,VM)
在线文本过滤小于指定长度工具
Simple understanding of counting and sorting
After crossing, she said that the multiverse really exists
带链接跳转的微信红包封面制作教程和使用指南
Zadig 构建究竟何强大?一起来实践
How to use the apipost script - global variables
00 後雲原生工程師:用 Zadig 為思創科技(廣州公交)研發開源節流
Code example of hiredis
DBNN实验进展
Summary of time series prediction series (code usage)
微搭低代码中实现二维码生成
Online linear programming: Dual convergence, new algorithms, and regret bounds
Zadig + SonarQube,为开发过程安全保驾
超级工厂里的生意图鉴
Common tool classes and Commons class libraries
What does project management really manage?