「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)
}
}
出力は同じです。遊び場に行く。