Goのpluginパッケージを試してみる
例えば強いこだわりにより、switchを使いたくない時
eg)
func main() { if len(os.Args) < 2 { fmt.Println(help()) os.Exit(1) } switch os.Args[1] { case "a": a.F() case "b": b.F() } }
Go1.8で導入されているpluginのパッケージを使えば以下のように書ける。
func main() { if len(os.Args) < 2 { fmt.Println(help()) os.Exit(1) } p, err := plugin.Open(os.Args[1] + ".so") if err != nil { fmt.Fprintf(os.Stderr, "Unexpected command: %s", err) os.Exit(1) } f, err := p.Lookup("F") if err != nil { fmt.Fprintf(os.Stderr, "Function F not found: %s", err) os.Exit(1) } f.(func())() }
トリックはそれぞれのファイルを-buildmode=plugin
でビルドすることでライブラリにしておき、さらにpluginパッケージにより動的に読み込んでしまう。
具体的には
1.ソースファイルを-buildmode=plugin
オプションでビルド
$ go build -buildmode=plugin a.go $ go build -buildmode=plugin b.go
2.main.goをビルドしたのち引数付きで実行
$ go build main.go $ ./main a This is a function in "a.go" $ ./main b This is a function in "b.go"
サンプルコード全体はgistに。
GoでもちょっとしたLL言語っぽいことができるみたい。