当前位置:网站首页>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())
}
}
边栏推荐
- Qt5.15中qsrand,srand随机数生成函数已弃用问题
- 全面掌握const的用法《一》
- Realization of 2D code generation in micro build low code
- Post-00 cloud native Engineer: use Zadig to increase revenue and reduce expenditure for the R & D of Sichuang Technology (Guangzhou public transport)
- 邂逅阿维塔 11:强产品力下久违的新鲜感
- The technology giants set up the meta universe standard forum to open up or build a besieged city?
- Explanation: Luogu p1762 even number /6.21 internal examination T2
- How to use London gold to draw support resistance line
- Ingénieur natif du nuage après 00: utiliser Zadig pour développer des sources ouvertes et des économies d'énergie pour la technologie innovante (bus de Guangzhou)
- 【Try to Hack】nmap
猜你喜欢

分享im即时通讯开发之WebSocket:概念、原理、易错常识

Linux安装mysql5.7(CentOS7.6) 教程

【深度学习】(2) Transformer 网络解析,代码复现,附Pytorch完整代码

How to analyze the trend chart of London gold market with the moving average

如何使用伦敦金画出支撑阻力线

Basic knowledge diagram of K-line Diagram -- meaning of single K-line

在线文本过滤小于指定长度工具

What does project management really manage?

Zadig officially launched vs code plug-in, making local development more efficient

QtCreator5.15.0源码编译全过程记录
随机推荐
Qsrand, srand random number generating function in qt5.15 has been discarded
How to use London gold to draw support resistance line
Linux安装mysql5.7(CentOS7.6) 教程
The new version of OpenAPI engine of Kingdee cloud dome is coming!
Zadig 构建究竟何强大?一起来实践
Zadig + sonarqube, ensuring the safety of the development process
直击产业落地 | 飞桨重磅推出业界首个模型选型工具
C#/VB.NET 将PDF转为Excel
This simple little function saves 213 hours for our production research team in half a year
Oracle删除归档日志及添加定时任务
Can we still enter the "pit" data analysis now? Look at the hot jobs of data analysis in 2022!
CPU、GPU、TPU、NPU区别
论文解读(DCN)《Towards K-means-friendly Spaces: Simultaneous Deep Learning and Clustering》
Production environment sonarqube installation
LeCun预言AGI:大模型和强化学习都是斜道!我的世界模型才是新路
Sample code of using redis to realize the like function
Career consultation | in the data analysis interview, it is only reliable to introduce yourself in this way
爱数SMART 2022峰会开启,分享数据战略与建设数据驱动型组织方法论
Powerful open source API interface visual management platform Yapi
00 后云原生工程师:用 Zadig 为思创科技(广州公交)研发开源节流