特別なプレフィックス/サフィックスを持つ関数を呼び出す 質問する

特別なプレフィックス/サフィックスを持つ関数を呼び出す 質問する

「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

編集1この例では、parentKeyはループ内で変更される文字列変数です。

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

しかしGCはこう言った。

セレクターなしのパッケージ シーダーの使用

ベストアンサー1

関数を名前で取得することはできません。それがあなたがしようとしていることです。その理由は、Goツールが関数が明示的に参照されていない(したがって到達できない)ことを検出した場合、実行可能バイナリにコンパイルされない可能性があるからです。詳細については、クライアント/サーバーコードの分割

関数レジストリ付き

必要なことを実行する 1 つの方法は、関数を呼び出す前に「関数レジストリ」を構築することです。

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

出力(遊び場に行く):

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

これを試してみてください遊び場に行く

注記:callByName()ヘルパー関数内で名前によって識別される関数を呼び出すか、関数値 (型func()) を返して呼び出し元の代わりに呼び出すかは、ユーザー次第です。

関数をメソッドに変換する

また、関数が実際には方法何らかの型であれば、レジストリなしでも実行できます。リフレクションを使用すると、名前でメソッドを取得できます。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)
    }
}

出力は同じです。遊び場に行く

おすすめ記事