This is a creation in Article, where the information may have evolved or changed.
Invocation of functions and methods in Golang reflection
The previous article talked about some of the basic rules of reflection in Golang, focusing on the last three points in the article, but this article does not say how to invoke functions and methods in reflection, which is the next step.
Calling a function in reflection
As we all know, the functions in Golang can be used as values like normal int, float and other types of variables, for example:
package mainimport "fmt"func hello() { fmt.Println("Hello world!")}func main() { hl := hello hl()}
Prints
hello world!
Since the function can be like a normal type variable, then in the reflection mechanism and different variables, in the reflection of the function and the type of the method (type) are Reflect.func, if you want to invoke the function, you can use the call method of value, for example:
func main() { hl := hello fv := reflect.ValueOf(hl) fmt.Println("fv is reflect.Func ?",fv.Kind() == reflect.Func) fv.Call(nil)}
Prints
fv is reflect.Func? truehello world!
The parameter of the call method of value is a value of slice, corresponding to the argument of the type of the reflection function, the return value is also a value of the slice, the same corresponds to the return value of the Reflection function type. With this example, I believe you will understand it at a glance:
func prints(i int) string { fmt.Println("i =",i) return strconv.Itoa(i)}func main() { fv := reflect.ValueOf(prints) params := make([]reflect.Value,1) //参数 params[0] := reflect.ValueOf(20) //参数设置为20 rs := fv.Call(params) //rs作为结果接受函数的返回值 fmt.Println("result:",rs[0].Interface().(string)) //当然也可以直接是rs[0].Interface()}
Prints
i = 20result: 20
Calling Methods in Reflection
It says the example of calling a function in reflection, and then we're going to talk about the invocation of the method in reflection. Functions and methods can be said to be essentially the same, except that the method is "bound" to an "object", which is a behavior of "object", which is a series of operations on the object, such as modifying a property of an object, such as the following:
type MyType struct {i int name String}func (Mt *mytype) SetI (i int) {mt.i = I}func (Mt *mytype) S Etname (name string) {Mt.name = Name}func (Mt *mytype) string () string {return FMT. Sprintf ("%p", MT) + "--name:" + mt.name + "I:" + StrConv. Itoa (MT.I)}
OK, now the type and its corresponding methods are ready, then how to use the problem, we have the above call function experience, only need to understand a little bit of knowledge can be used, this knowledge is method and Methodbyname API, OK, now all ready, Let's see how to use it.
func main() { myType := &MyType{22,wowzai} //fmt.Println(myType) //就是检查一下myType对象内容 //println("---------------") mtV := reflect.ValueOf(&myType).Elem() fmt.Println("Before:",mtV.MethodByName("String").Call(nil)[0]) params := make([]reflect.Value,1) params[0] = reflect.ValueOf(18) mtV.MethodByName("SetI").Call(params) params[0] = reflect.ValueOf("reflection test") mtV.MethodByName("SetName").Call(params) fmt.Println("After:",mtV.MethodByName("String").Call(nil)[0])}
Prints
Before: address:0x18245050--name:wowzai i:22After: address:0x18245050--name:reflection test i:18
Note that the address printed above is the address of the object in memory, if you also run this code, the result of this address should be different.
Hey, is this the end of it? Of course not, careful readers will find the above mentioned method seems useless ah, well, yes, smart you look at the introduction of the API I believe you will know how to convert the above code into the method to achieve the same effect:
mtV := reflect.ValueOf(&myType).Elem()fmt.Println("Before:",mtV.Method(2).Call(nil)[0])params = make([]reflect.Value,1)params[0] = reflect.ValueOf(18)mtV.Method(0).Call(params)params[0] = reflect.ValueOf("reflection test")mtV.Method(1).Call(params)fmt.Println("After:",mtV.Method(2).Call(nil)[0])
The effect of printing is the same as the example above (the address may be different), well, here basically the reflection function and method of the call basically finished, but really ended? Is there any other way to do it? Well, you can always get what you want from a smart one.
---if there is a mistake, please correct it---