• 在 Golang 中用名字调用函数


    https://studygolang.com/articles/1035

    首先,来看看这段 PHP 代码:

    function foobar() {
        echo "Hello Golang
    ";
    }
    $funcs = array(
        "foobar" => "foobar",
        "hello"  => "foobar",
    );
    $funcs["foobar"]();
    $funcs["hello"]();
    

    它会输出:

    mikespook@mikespook-laptop:~/Desktop$ php foobar.php 
    Hello Golang
    Hello Golang
    

    用这个方法调用匹配名字的函数,非常有效。

    那么,在 Golang 中是否可能用函数的名字来调用某个函数呢?

    作为一个静态、编译型语言,答案是否定的……又是肯定的

    在 Golang 中,你不能这样做:

    func foobar() {
        // bla...bla...bla...
    }
    funcname := "foobar"
    funcname()
    

    不过可以:

    func foobar() {
        // bla...bla...bla...
    }
    funcs := map[string]func() {"foobar":foobar}
    funcs["foobar"]()
    

    但这里有一个限制:这个 map 仅仅可以用原型是“func()”的没有输入参数或返回值的函数。
    如果想要用这个方法实现调用不同函数原型的函数,需要用到 interface{}。

    是啊!interface{},跟 C 中的 void 指针类似。还记得这个东西吗?不记得了?没事,看看这个吧:《The Go Programming Language Specification:Interface types》。

    这样,就可以添加有着不同函数原型的函数到一个 map 中:

    func foo() {
        // bla...bla...bla...
    }
    func bar(a, b, c int) {
        // bla...bla...bla...
    }
    funcs := map[string]interface{}{"foo":foo, "bar":bar}
    

    那么如何调用 map 中的函数呢?像这样吗:

    funcs["foo"]()
    

    绝对不行!这无法工作!你不能直接调用存储在空接口中的函数。

    反射走进我们的生活!在 Golang 中有着叫做“reflect”的包。你是否了解反射了呢?
    如果还没有,那么阅读一下这个:《Laws of reflection》吧。哦,这里有个中文版本:《反射的规则》。

    func Call(m map[string]interface{}, name string, params ... interface{}) (result []reflect.Value, err error) {
        f = reflect.ValueOf(m[name])
        if len(params) != f.Type().NumIn() {
            err = errors.New("The number of params is not adapted.")
            return
        }
        in := make([]reflect.Value, len(params))
        for k, param := range params {
            in[k] = reflect.ValueOf(param)
        }
        result = f.Call(in)
        return
    }
    Call(funcs, "foo")
    Call(funcs, "bar", 1, 2, 3)
    

    将函数的值从空接口中反射出来,然后使用 reflect.Call 来传递参数并调用它。
    没有什么是很难理解的。

    参考Demo:https://bitbucket.org/mikespook/golib/src/27c65cdf8a77/funcmap.

  • 相关阅读:
    简单项目却持着一颗纠结的心
    一个简单的打的系统
    ftqghkwiNdrpid快速建项Sql语句生
    3/21 Django框架 模板路径及模板过滤器 1.模板路径查找
    3/19 Django框架 url路由配置及模板渲染
    3/18 Django框架 启动django服务
    3/16 Django框架 环境搭建
    Windows子系统配置,cmder配置, pycharm配置django开发环境
    Requests+正则表达式抓取猫眼电影TOP100
    分析Ajax抓取今日头条街拍美图
  • 原文地址:https://www.cnblogs.com/rxbook/p/15223988.html
Copyright © 2020-2023  润新知