原文:https://vimsky.com/zh-tw/examples/usage/reflect-methodbyname-function-in-golang-with-examples.html
------------------------------
Go語言提供了運行時反射的內置支持實現,並允許程序借助反射包來操縱任意類型的對象。 Golang中的reflect.MethodByName()函數用於獲取與具有給定名稱的v方法相對應的函數值。要訪問此功能,需要在程序中導入反射包。
用法:
func (v Value) MethodByName(name string) Value
參數:此函數不接受任何參數。
返回值:此函數返回與具有給定名稱的v方法相對應的函數值。
以下示例說明了以上方法在Golang中的用法:
範例1:
// Golang program to illustrate
// reflect.MethodByName() Function
package main
import (
"fmt"
"reflect"
)
// Main function
type T struct {}
func (t *T) GFG() {
fmt.Println("GeeksForGeeks")
}
func main() {
var t T
reflect.ValueOf(&t).MethodByName("GFG").Call([]reflect.Value{})
}
輸出:
GeeksForGeeks
範例2:
// Golang program to illustrate
// reflect.MethodByName() Function
package main
import (
"fmt"
"reflect"
)
// Main function
type YourT2 struct {}
func (y YourT2) MethodFoo(i int, oo string) {
fmt.Println(i)
fmt.Println(oo)
}
func Invoke(any interface{}, name string, args... interface{}) {
inputs:= make([]reflect.Value, len(args))
for i, _:= range args {
inputs[i] = reflect.ValueOf(args[i])
}
reflect.ValueOf(any).MethodByName(name).Call(inputs)
}
func main() {
Invoke(YourT2{}, "MethodFoo", 10, "Geekforgeeks")
}
輸出:
10 Geekforgeeks
-------------------------------------
https://stackoverflow.com/questions/32673407/dynamic-function-call-in-go
First, let me remark that func() (interface{})
means the same thing as func() interface{}
, so I'll use the shorter form.
Passing a function of type func() interface{}
You can write a generic function that takes a func() interface{}
argument as long as the function that you pass to it has type func() interface{}
, like this:
type A struct {
Name string
Value int
}
type B struct {
Name1 string
Name2 string
Value float64
}
func doA() interface{} {
return &A{"Cats", 10}
}
func doB() interface{} {
return &B{"Cats", "Dogs", 10.0}
}
func Generic(w io.Writer, fn func() interface{}) {
result := fn()
json.NewEncoder(w).Encode(result)
}
You can try out this code in a live playground:
http://play.golang.org/p/JJeww9zNhE
Passing a function as an argument of type interface{}
If you want to write functions doA
and doB
that return concretely typed values, you can pass the chosen function as an argument of type interface{}
. Then you can use the reflect
package to make a func() interface{}
at run-time:
func Generic(w io.Writer, f interface{}) {
fnValue := reflect.ValueOf(f) // Make a concrete value.
arguments := []reflect.Value{} // Make an empty argument list.
fnResults := fnValue.Call(arguments) // Assume we have a function. Call it.
result := fnResults[0].Interface() // Get the first result as interface{}.
json.NewEncoder(w).Encode(result) // JSON-encode the result.
}
More concisely:
func Generic(w io.Writer, fn interface{}) {
result := reflect.ValueOf(fn).Call([]reflect.Value{})[0].Interface()
json.NewEncoder(w).Encode(result)
}
Complete program:
package main
import (
"encoding/json"
"io"
"os"
"reflect"
)
type A struct {
Name string
Value int
}
type B struct {
Name1 string
Name2 string
Value float64
}
func doA() *A {
return &A{"Cats", 10}
}
func doB() *B {
return &B{"Cats", "Dogs", 10.0}
}
func Generic(w io.Writer, fn interface{}) {
result := reflect.ValueOf(fn).Call([]reflect.Value{})[0].Interface()
json.NewEncoder(w).Encode(result)
}
func main() {
Generic(os.Stdout, doA)
Generic(os.Stdout, doB)
}
Live playground: