By coditori


2016-05-23 07:00:17 8 Comments

I have a package named "seeder":

package seeder

import "fmt"

func MyFunc1() {
    fmt.Println("I am Masood")
}

func MyFunc2() {
    fmt.Println("I am a programmer")
}

func MyFunc3() {
    fmt.Println("I want to buy a car")
}

Now I want to call all functions with MyFunc prefix

package main

import "./seeder"

func main() {
    for k := 1; k <= 3; k++ {
        seeder.MyFunc1() // This calls MyFunc1 three times
    }
}

I want something like this:

for k := 1; k <= 3; k++ {
    seeder.MyFunc + k ()
}

and this output:

I am Masood
I am a programmer
I want to buy a car

EDIT1: In this example, parentKey is a string variable which changed in a loop

for parentKey, _ := range uRLSjson{ 
    pppp := seeder + "." + strings.ToUpper(parentKey)
    gorilla.HandleFunc("/", pppp).Name(parentKey)
}

But GC said:

use of package seeder without selector

2 comments

@icza 2016-05-23 07:11:07

You can't get a function by its name, and that is what you're trying to do. The reason is that if the Go tool can detect that a function is not referred to explicitly (and thus unreachable), it may not even get compiled into the executable binary. For details see Splitting client/server code.

With a function registry

One way to do what you want is to build a "function registry" prior to calling them:

registry := map[string]func(){
    "MyFunc1": MyFunc1,
    "MyFunc2": MyFunc2,
    "MyFunc3": MyFunc3,
}
for k := 1; k <= 3; k++ {
    registry[fmt.Sprintf("MyFunc%d", k)]()
}

Output (try it on the Go Playground):

Hello MyFunc1
Hello MyFunc2
Hello MyFunc3

Manual "routing"

Similar to the registry is inspecting the name and manually routing to the function, for example:

func callByName(name string) {
    switch name {
    case "MyFunc1":
        MyFunc1()
    case "MyFunc2":
        MyFunc2()
    case "MyFunc3":
        MyFunc3()
    default:
        panic("Unknown function name")
    }
}

Using it:

for k := 1; k <= 3; k++ {
    callByName(fmt.Sprintf("MyFunc%d", k))
}

Try this on the Go Playground.

Note: It's up to you if you want to call the function identified by its name in the callByName() helper function, or you may choose to return a function value (of type func()) and have it called in the caller's place.

Transforming functions to methods

Also note that if your functions would actually be methods of some type, you could do it without a registry. Using reflection, you can get a method by name: Value.MethodByName(). You can also get / enumerate all methods without knowing their names using Value.NumMethod() and Value.Method() (also see Type.NumMethod() and Type.Method() if you need the name of the method or its parameter types).

This is how it could be done:

type MyType int

func (m MyType) MyFunc1() {
    fmt.Println("Hello MyFunc1")
}

func (m MyType) MyFunc2() {
    fmt.Println("Hello MyFunc2")
}

func (m MyType) MyFunc3() {
    fmt.Println("Hello MyFunc3")
}

func main() {
    v := reflect.ValueOf(MyType(0))
    for k := 1; k <= 3; k++ {
        v.MethodByName(fmt.Sprintf("MyFunc%d", k)).Call(nil)
    }
}

Output is the same. Try it on the Go Playground.

@coditori 2016-05-23 07:13:24

Thank but is there any other way without map?

@icza 2016-05-23 07:16:09

@MasoodAfrashteh You may do it with a registry, or by transforming functions to methods. Having functions and no registry - you can't.

@Jiang YD 2016-05-23 07:19:09

or reflect, which helping turn string to function.

@coditori 2016-05-23 07:19:51

Please see the edit1 part thanks

@icza 2016-05-23 07:22:06

@JiangYD You can't get a function by name using reflect, only methods.

@icza 2016-05-23 07:23:36

@MasoodAfrashteh Considering your edit to the question, the answers still stand: you can't do it without a registry or using methods instead of functions.

@coditori 2016-05-23 07:30:40

Thanks I just change MyType type to string It's working.

@Jiang YD 2016-05-23 07:32:31

yes I missed it. why golang designed not get to Package at runtime?

@coditori 2016-05-23 07:43:28

Sorry It's not working because in my example functions write by user and I'm going to connect those functions with special prefix or suffix like "route" to gorilla.

@icza 2016-05-23 07:47:06

@MasoodAfrashteh As said previously, if they remain functions (and you can't make them methods), you can only do it with a function registry (or some other construct, explicitly listing the names, routing them to functions manually).

@Liyan Chang 2018-11-03 01:02:27

Another alternative would be to range over an array of your functions

package main

import (
    "fmt"
)

func MyFunc1() {
    fmt.Println("I am Masood")
}

func MyFunc2() {
    fmt.Println("I am a programmer")
}

func MyFunc3() {
    fmt.Println("I want to buy a car")
}


func main() {
   for _, fn := range []func(){MyFunc1, MyFunc2, MyFunc3} {
        fn()
    }
}

Related Questions

Sponsored Content

18 Answered Questions

[SOLVED] Javascript call() & apply() vs bind()?

10 Answered Questions

[SOLVED] What does the exclamation mark do before the function?

  • 2010-09-20 21:21:51
  • Sebastian Otto
  • 149958 View
  • 1157 Score
  • 10 Answer
  • Tags:   javascript function

24 Answered Questions

[SOLVED] Set a default parameter value for a JavaScript function

38 Answered Questions

[SOLVED] var functionName = function() {} vs function functionName() {}

5 Answered Questions

[SOLVED] Why can't I put the opening braces on the next line?

  • 2011-08-15 06:39:21
  • Anuj Verma
  • 693 View
  • 2 Score
  • 5 Answer
  • Tags:   error-handling go

7 Answered Questions

[SOLVED] Ukkonen's suffix tree algorithm in plain English

30 Answered Questions

[SOLVED] startsWith() and endsWith() functions in PHP

  • 2009-05-07 12:14:27
  • Click Upvote
  • 783841 View
  • 1373 Score
  • 30 Answer
  • Tags:   php string

10 Answered Questions

[SOLVED] How to get a function name as a string in Python?

20 Answered Questions

[SOLVED] What is the difference between call and apply?

31 Answered Questions

[SOLVED] What's the difference between a method and a function?

Sponsored Content