我有一个名为" 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")
}

现在我想用MyFunc前缀调用所有函数

package main

import "./seeder"

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

我想要这样的东西:

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

输出如下:

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

EDIT1: 在本例中,parentKey是在循环中更改的字符串变量

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

但是GC说:

不带 Select 器的打包 seeder 机的使用

推荐答案

您不能按名称获取函数,这就是您要try 做的事情.原因是,如果Go工具可以检测到某个函数没有被显式引用(因此无法访问),那么它甚至可能不会编译成可执行的二进制文件.有关详细信息,请参见Splitting client/server code.

带有函数注册表

一种方法是在调用函数之前构建一个"函数注册表":

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

输出(在Go Playground上试用):

Hello MyFunc1
Hello MyFunc2
Hello MyFunc3

手动"布线"

与注册表类似的是,判断名称并手动路由到函数,例如:

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

使用它:

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

Go Playground号上试试这个.

Note:您可以在callByName()助手函数中调用由其名称标识的函数,也可以 Select 返回一个函数值(类型为func())并在调用者的位置进行调用.

将函数转换为方法

还要注意,如果您的函数实际上是methods个某种类型的函数,那么您可以在没有注册表的情况下完成它.使用反射,您可以获得名称为Value.MethodByName()的方法.您还可以使用Value.NumMethod()Value.Method()在不知道名称的情况下获取/枚举所有方法(如果需要方法名称或其参数类型,请参阅Type.NumMethod()Type.Method()).

这是可以做到的:

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)
    }
}

输出是相同的.在Go Playground号公路上试试吧.

Go相关问答推荐

Golang ==错误:OCI运行时创建失败:无法启动容器进程:exec:./" bin:stat./" bin:没有这样的文件或目录:未知

Go:嵌入类型不能是类型参数""

如何存储来自异步Goroutine的返回值列表?

如何使用 html/template 在 golang 中运行一个范围内的范围

生成一个 CSV/Excel,在 Golang 中该列的下拉选项中指定值

Go - 永远停止带有上下文的循环

在 Go 中使用 Apache Arrow 按时间间隔对事件进行分区

如何解决我的 Go 聊天应用程序中 cookie 未在本地主机端口之间传输的问题?

使用模拟在 golang 中测试我的界面.专门测试调用同级函数的 1 个函数

如何使用名称具有包名称的嵌套 struct 启动 go struct

是否可以从 golang 中的参数推断类型?

如何使用 Docker 引擎 SDK 和 Golang 运行 docker 挂载卷

速率限制特定端点

在 Gorm 的 AfterFind() 钩子中获取智能 Select struct 的值

在 connect-go 拦截器中修改响应体

如何在 Windows 中使用 github.com/AllenDang/giu 和 github.com/gordonklaus/portaudio 构建 GO 程序

在 Go 中将指针传递给函数的正确方法是什么,以便我可以读取和/或修改指针表示的值?

有没有办法在一个 goroutine 返回后延迟后取消上下文?

Golang 有类似 C++ 的 decltype 的东西吗?

如何从 docker-compose 命令运行 2 个不同的命令: