Вызов функций со специальным префиксом / суффиксом
У меня есть пакет с именем "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 сказал:
использование пакетной сеялки без селектора
2 ответа
Вы не можете получить функцию по имени, и это то, что вы пытаетесь сделать. Причина в том, что если инструменты 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.
Примечание: вам решать, хотите ли вы вызвать функцию, указанную в 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)
}
}
Выход такой же. Попробуйте это на игровой площадке Go.
Другой альтернативой было бы расширить диапазон ваших функций
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()
}
}