2016-06-16 13 views
1

はへのアクセスを取得する方法はありますのは、私はいくつかのパッケージgolangにパッケージからエクスポートされた関数のリストを取得する

// ./somepkg/someFile.go 
package somepkg 
import "fmt" 
func AnExportedFunc(someArg string) { 
    fmt.Println("Hello world!") 
    fmt.Println(someArg) 
) 

を持っていると私は私のメインのゴーファイル

// ./main.go 
package main 
import (
    "./somepkg" // Let's just pretend I have the full path written out 
    "fmt" 
) 

func main() { 
    fmt.Println("I want to get a list of exported funcs from package 'somefolder'") 
} 

からインポートするとしましょうパッケージ「somepkg」からエクスポートされた関数を呼び出し、結果としてそれらを呼び出すことができますか?引数の数/型はsomepkgのすべての関数で一貫しています。私はリフレクションパッケージを見てきましたが、パッケージ名以外の情報を知らなくてもリストを取得して関数を呼び出すことができるかどうかはわかりません。しかし、私はgiefから何かを逃しているかもしれないので、どんなアドバイスも感謝します。私がしようとしているのは、本質的に、人々が.goファイルを一種の「プラグイン」としてドロップできるシステムです。これらの "プラグイン"には、メインプログラム自体が一貫した数とタイプのargsで呼び出す単一のエクスポート関数があります。このコードベースへのアクセスは制限されているため、コントリビュータによる任意のコード実行に関するセキュリティ上の問題はありません。

注:なし実行時の制限がないので、これはすべてコンパイルされ

Pythonで書かれている場合、このようなものは、私は何をしようとしているある

# test.py 
def abc(): 
    print "I'm abc" 

def cba(): 
    print "I'm cba" 

# foo.py 
import test 
flist = filter(lambda fname: fname[0] != "_", dir(test)) 

# Let's forget for a moment how eval() is terrible 
for fname in flist: 
    eval("test."+fname+"()") 

foo.pyを返すと、

I'm abc 
I'm cba 

これはゴランで可能ですか?

編集:

私はすでにhttp://mikespook.com/2012/07/function-call-by-name-in-golang/に非常によく似たもので、これを「達成」していることに注意したが、それぞれ追加の「プラグイン」は、パッケージのグローバルマップへのエクスポート機能を追加することを要求すべきです。これは "うまくいく"とはいえ、これはハッキリしているようです(この全体のプログラムが...笑わないように)、プラグイン作家の追加作業を必要とせずにやることができれば好きです。基本的には、できるだけ「ドロップアンドゴー」としたいと思っています。

+0

エクスポートされたシンボルは、コンパイル時にのみ使用できるため、実行時には取得できません。関数が使用されていない場合は、リンク中に削除されます。 (現在のgcの実装では) – JimB

+0

私は実行時にメインプログラム自体に "プラグイン"をコンパイルするので、それらは必要ありません。私はそれが "プラグイン"なので、それを引用するのは奇妙だと思います。私は主にast、トークン、パーサー、パッケージを見ていましたが、やりたいことをいくらか実行することは可能ですが、方法についてはあまりよく分かりません。 – user1522031

+1

コンパイル時に何かしたいのであれば、反映パッケージはあなたを助けません。コンパイルする前に、ソースを解析し、各プラグインに必要なコードを生成する必要があります。 – JimB

答えて

0

これを行う最も簡単な方法は、templateライブラリを使用してコードを解析し、必要に応じて新しいパッケージ名を挿入することです。

Playground

あなたはユーザーパッケージと、出力実行ディレクトリに生成されたファイルを呼び出す決勝戦の全てをロードすることによって、これを使用することができます。

関連する問題