为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
月关宝盒 2022-01-10 19:05:05
我有一个名为“播种机”的包:package seederimport "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 mainimport "./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 MasoodI am a programmerI want to buy a carEDIT1:在这个例子中,parentKey 是一个在循环中改变的字符串变量for parentKey, _ := range uRLSjson{     pppp := seeder + "." + strings.ToUpper(parentKey)    gorilla.HandleFunc("/", pppp).Name(parentKey)}但是GC说:使用没有选择器的包播种器
查看完整描述

2 回答

?
一只萌萌小番薯

TA贡献1795条经验 获得超7个赞

你不能通过它的名字来获得一个函数,这就是你想要做的。原因是如果 Go 工具可以检测到一个函数没有被显式引用(因此无法访问),它甚至可能不会被编译成可执行的二进制文件。有关详细信息,请参阅拆分客户端/服务器代码。


带有函数注册表

做你想做的事情的一种方法是在调用它们之前构建一个“函数注册表”:


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上试试这个。


注意:是否要在callByName()帮助函数中调用由其名称标识的函数取决于您,或者您可以选择返回一个函数值(类型为func())并在调用者的位置调用它。


将函数转换为方法

另请注意,如果您的函数实际上是某种类型的方法,您可以在没有注册表的情况下执行此操作。使用反射,您可以通过名称获取方法:Value.MethodByName(). 您还可以使用Value.NumMethod()and 在不知道其名称的情况下获取/枚举所有方法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上尝试一下。


查看完整回答
反对 回复 2022-01-10
?
红颜莎娜

TA贡献1842条经验 获得超12个赞

另一种选择是覆盖你的函数数组


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

    }

}


查看完整回答
反对 回复 2022-01-10
  • 2 回答
  • 0 关注
  • 146 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信