dongtaotao19830418 2016-05-23 07:00
浏览 122
已采纳

带有特殊前缀/后缀的调用函数

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条回答 默认 最新

  • dqbhdsec59405 2016-05-23 07:11
    关注

    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.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 关于#matlab#的问题:在模糊控制器中选出线路信息,在simulink中根据线路信息生成速度时间目标曲线(初速度为20m/s,15秒后减为0的速度时间图像)我想问线路信息是什么
  • ¥15 banner广告展示设置多少时间不怎么会消耗用户价值
  • ¥16 mybatis的代理对象无法通过@Autowired装填
  • ¥15 可见光定位matlab仿真
  • ¥15 arduino 四自由度机械臂
  • ¥15 wordpress 产品图片 GIF 没法显示
  • ¥15 求三国群英传pl国战时间的修改方法
  • ¥15 matlab代码代写,需写出详细代码,代价私
  • ¥15 ROS系统搭建请教(跨境电商用途)
  • ¥15 AIC3204的示例代码有吗,想用AIC3204测量血氧,找不到相关的代码。