Go

定義されている関数のリストをリフレクションを使っても取得できない理由

More than 3 years have passed since last update.

Goのリフレクション(reflect)を使うと構造体のフィールドのリストやインターフェイスのメソッドセットを取得することができる。しかし定義されている関数のリストを取得することはできない。reflectはそういう機能を提供していないのである。

どうも、設定ファイルから関数名を読んで、その関数を呼び出すといったことをやりたいといったような話が定期的にあがってくるようだ。たしかにそういうことができれば便利かもしれないが、そういう機能を提供していないのにはきちんとした理由がある

Goでは使われていない関数は最終的なバイナリには入らない。定義されているけどどこからも呼ばれていない関数というのは最初から書いていないのと同じだ。逆に言うと、コンパイラとリンカに関数を削除するという最適化を許すためには、関数一覧を取得するという機能があったりすると困るのである。

では実際に使われている関数だけの一覧を取得できればよいのでは? と思うかもしれないが、関数がインライン展開されていたりすると、その関数は、使われていてもランタイムには独立した関数としては存在しないことがありえる。それに、関係ない場所をいじったらメタプログラミングしている場所の振る舞いが変わるといった調子だとわかりにくくて仕方がない。だから関数一覧を取得する機能は単に提供しない、というのはいい割り切りだと思う。

なお、どうしても関数を名前で呼びたいときは、関数名→関数のマップを作っておいてそれを実行時にルックアップすればよい。