Function call by name in Golang

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

The golang’s function is a code block like C’s, but it can also be assigned to a variable as its other types.

If you are not familiar with the function, Codewalk: First-Class Functions in Go should be a good starting point for you. Already known it? Let’s go on.

First of all, look at this PHP codes:

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

It will print:

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

It is very useful for calling a function with name matching.

So, is it possible to call a function by its name in Golang?
As a static, compiled programming language, the answer is No … and YES!

You can not do this in Golang:

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

You can do:

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

But here’s a limitation that the map only work with the prototype “func()”, no input parameters and return arguments.
If you want to call some functions have different function’s prototypes, the interface{} should be used.

Yep! interface{}, like the void pointer in C. Remember that? No? Never mind! Read this: The Go Programming Language Specification:Interface types.

Then we could add functions with different prototypes into one map:

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

How to call a function in the map? like this?

funcs["foo"]()

NO! It does not work! You can not call a function stored in a empty interface variable directly.
Dadadada…

Reflection comes to us! It is a package called “reflect” in Golang. Do you know reflection already?
If not, just read this: 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)

Reflecting the function variable, use reflect.Call to call it and pass parameters into it at the same time.
Nothing could be hard to understand.

I’ve done a package for this functional: https://bitbucket.org/mikespook/golib/src/27c65cdf8a77/funcmap.

Hope this helps. Have a good time, gophers!

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.