在 Golang 中用名字调用函数

在 Golang 中用名字调用函数,第1张

概述上个星期,我写了篇《Function call by name in Golang》。由于是英文的,所以被人诟病(说谁,谁知道!)。好吧,现在用中文重新写一遍。 Golang 中的函数跟 C 的一样,是个代码块,不过它可以像其他类型那样赋值给一个变量。 如果你对函数不熟悉,《Codewalk: First-Class Functions in Go》应该是个不错的起点。已经有所了解?那么继续吧!

上个星期,我写了篇《Function call by name in Golang》。由于是英文的,所以被人诟病(说谁,谁知道!)。好吧,现在用中文重新写一遍。

Golang 中的函数跟 C 的一样,是个代码块,不过它可以像其他类型那样赋值给一个变量。

如果你对函数不熟悉,《Codewalk: First-Class Functions in Go》应该是个不错的起点。已经有所了解?那么继续吧!

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

functionfoobar() { echo"Hello Golang\n"; } $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,cint) { // bla...bla...bla... } funcs := map[string]interface{}{"foo":foo,"bar":bar}

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

funcs["foo"]()

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

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

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

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

我已经完成了一个包来实现这个功能,在这里:https://bitbucket.org/mikespook/golib/src/27c65cdf8a77/funcmap.

希望这有些帮助。好运,地鼠们!

总结

以上是内存溢出为你收集整理的在 Golang 中用名字调用函数全部内容,希望文章能够帮你解决在 Golang 中用名字调用函数所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1291789.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-10
下一篇 2022-06-10

发表评论

登录后才能评论

评论列表(0条)

保存