给定包含具有不同参数的函数的接口以及该接口的具体实现,如何从该接口基于该字节流获取字节流和调用方法。基本上是一个RPC调用。
e.g。
type funcs interface {
func Hello(name string) (string, error)
func Add(numbers...int) (result, error)
}
让我说我有以下输入数据
Hello John
Add 1 2 3 4
我认为这必须用反射来完成,但这个包我觉得有点神秘。不是很好的例子。看看RPC包也有点神秘。我不明白他们在做什么,似乎有限制或假设,也许是为了使代码更简单和/或更快实现。
有人可以说明我如何接受字符串"你好"并找到函数句柄" Hello"来自funcs表。并且知道它期望单个参数是一个字符串,然后使用提供的参数调用该函数" John"。
答案 0 :(得分:1)
您可以使用reflect
包执行此操作(有关性能和代码可读性的一般警告适用)。只需创建一个类型并实现该类型的函数,然后在从该类型的实例创建的Value
上调用reflect.MethodByName():
package main
import (
"fmt"
"reflect"
)
type functions struct {}
func (f functions) Hello(name string) (string, error) {
fmt.Println("Hello,", name)
return name, nil
}
func main() {
var f functions
m := reflect.ValueOf(f).MethodByName("Hello")
if m.IsValid() {
// Either call f.Hello() here, or use the returned Value like so:
v := make([]reflect.Value, 1) // function Values only take Value slices as arguments
v[0] = reflect.ValueOf("Asha")
r := m.Call(v)
fmt.Println("Returned", r)
}
}
打印:
Hello, Asha
Returned [Asha <error Value>]
(见https://play.golang.org/p/0q1i3WBuAL)
但是,如果您知道希望能够调用先验的函数名称,或者您希望用户能够使用除确切函数名称以外的名称,那么只需使用switch
或if
/ else
声明:
package main
import (
"fmt"
"strings"
)
func Hello(name string) {
fmt.Println("Hello,", name)
}
func main() {
userInput := make([]string, 2)
userInput[0] = "HeLlO"
userInput[1] = "재은"
switch(strings.ToLower(userInput[0])) { // allow any case
case "hello":
Hello(userInput[1])
default:
panic("user input not recognized")
}
}
打印:
Hello, 재은