私はパッケージ名( "my/package/test"など)の文字列を持っており、それをインポートしてパッケージからいくつかの関数を呼び出す必要があります。このようなGoの文字列からパッケージをパスでインポートする方法は?
何か:
func init() {
var pkg string = "test/my/pkg"
import pkg
pkg.Test()
}
PS。助けてくれてありがとう
私はパッケージ名( "my/package/test"など)の文字列を持っており、それをインポートしてパッケージからいくつかの関数を呼び出す必要があります。このようなGoの文字列からパッケージをパスでインポートする方法は?
何か:
func init() {
var pkg string = "test/my/pkg"
import pkg
pkg.Test()
}
PS。助けてくれてありがとう
Go言語では、あなたの例で言及したことを許可していません。これは意識的な選択です。私の意見では、この選択の背後にある理由は、コンパイラのパフォーマンスとマシンによるコードの理解の容易さと関係しています。たとえば、gofixのようなツールでは、ユーザーの介入なしにGoコードを部分的に修正できます。
プログラマは、プログラムで使用されている静的にインポートされたパッケージをすべて明示的に表示することもできます。
Go言語仕様のsource file organizationの文法規則も参照してください。
実行時にパッケージを動的にロードすることに関して:実行時にパッケージをロードする機能はありません。将来のGo実行時にこの機能を実装するかもしれません(たとえば、golang-nutsメーリングリストのメッセージで要求されることがあります)が、現在の状態ではこの機能はサポートされていません。
Goではこれができません。リンカーはコンパイル時に依存関係を知る必要がありますが、文字列(およびinit関数)は実行時に評価されます。また、使用されていないプログラム、つまり明示的に参照されていない部分は、最終的なバイナリの一部でもないので、リフレクションも不可能です。
このようなものが必要な場合は、自分でマッピングを管理する必要があります。たとえば、あるパッケージでグローバルマップを使用し、他のパッケージのinit関数を使用して、関連する関数をマップに追加して登録することができます。その後、マップを使用してルックアップを動的に行うことができます。
たとえば、httpパッケージを見てください。架空のブログパッケージでは、blog.init()関数を使用して、http.HandleFunc(パターン、ハンドラー)関数を使用していくつかのhttpハンドラーを登録できます。メインパッケージは、実行時に右ハンドラを検索するhttp.ListenAndServe()を呼び出すことがあります。
大丈夫です。私は別の質問があります。 PHPのcall_user_funcのように、名前からパッケージから関数を呼び出す方法は? – Rusfearuth
@Rusfearuthは 'reflect'パッケージを見ています。 –