初心者向けにGoをご紹介した資料です。
Goでの開発が未経験でどんな特徴があるのか知りたいひと向けに簡単にメリット・デメリットをまとめています。
今回はサードパーティのライブラリーを使うと簡単にCLIが実装できるという導入のお話をまとめています。 ライブラリーを簡単に取得しCLIの骨組みが生成できること、生成された骨組みのコードからGoがシンプルな記述になっていることを理解してもらえたらと思います。
この資料をきっかけにGoの活用をご検討していただけたら幸いです。
エンプラでも活⽤できる︕Goのご紹介〜初級者編〜倉林 雅
View Slide
はじめに• 「エンプラでも活⽤できる」とありますが、内容はエンタープライズに特化したものではなくGoの基礎を中⼼に整理したものです• Goのメリット・デメリットやサードパーティのライブラリーを使ったCLIの導⼊などを簡単にまとめています• エンタープライズの環境でGoの活⽤の検討につなげられたらと考えております2
倉林 雅(くらはやし まさる)• OpenIDファウンデーション・ジャパン• 理事• エバンジェリスト• ヤフー株式会社• ID・セキュリティユニット• CISO室• エンジニア• https://twitter.com/kura_lab3
担当業務・活動• OAuth/OpenID Connectの開発・運⽤• Yahoo! ID連携(IdP)• スマートログイン(RP)など• ID関連のセキュリティ推進• 認証・認可技術の普及・啓発活動• ID基盤関連のコンサルティング業務4
開発の経験• 学⽣時代• CとJavaの基礎を学ぶ• 群集歩⾏者シミュレーションをJavaで実装• ヤフーでの業務• PHP(⼀部C++)でID基盤やOpenID Connectサーバー(IdP)を開発• ヤフー公式のAndroidアプリの認証・認可機能を開発• 趣味• GoによるOpenID Connectクライアント(RP)を実装中• AWS上にSPAアプリケーションを実装など• Github• https://github.com/kura-lab5
Goとは• 2009年にGoogleから発表されたプログラミング⾔語• BSDライセンスのオープンソース• https://github.com/golang/go• 改良されたC⾔語• 読解性・⽣産性・⾼速性に優れている• リポジトリはgithub.comGopher6
メリット 1/2• VM(仮想マシン)を持たず実⾏環境が不要• ビルドすることで動作する環境に適合した実⾏ファイル(バイナリー)が⽣成される• マルチプラットフォームで動作する• CPUやOSの差異を吸収してくれる• サードパーティ製のライブラリーが多くある• Googleだけでなく、DockerやDropBoxなどでも利⽤されており、Github上で多くのライブラリーが提供されている• デプロイが容易• バイナリーを配置するのみ• ガベージコレクションがある• メモリリーク、バッファオーバーフローを解消7
メリット 2/2• 並列処理• スレッドよりも⼩さい単位のgoroutineを提供• ⾔語機能や⽂法がシンプル• IDEがなくても開発ができる• スクリプト⾔語より⾼速• ネイティブコードにコンパイルされているため実効性能がよい• 命名規則があるためシンプルになる• パッケージや関数を⼩さくする必要が出てくるため、疎結合になりテストしやすくなり可読性も上がる8
デメリット 1/2• 実⾏ファイルが⼤きくなることがある• 各OSが個別に提供する共通ライブラリーは利⽤できないため全てを実⾏ファイルに含める必要がある• LinuxやWindowsの固有のOS依存を利⽤するケースは稀であるため⼤きな問題ではない• オブジェクト指向⾔語ではない• オブジェクト指向な実装もできなくはないが、Javaなどに⽐べると機能が⽋けている• 構造体、関数などシンプルな機能を提供• 低レベルな処理の理解• パフォーマンスを出すためにはスタック、ヒープなどを理解する必要がある• ソースファイルに名前空間がない• 同⼀のディレクトリでファイルを分けても名前空間は同じになるため、変数名や関数名を分ける必要がある9
デメリット 2/2• 例外処理がない• Exceptionのthrowができないが、エラーを処理するためのerrorインターフェースがある• オーバーロードや継承がない• JavaやC++でできていたオブジェクト指向な実装が難しい部分がある• フロントエンドのレンダリングには不向き• MVCモデルなどフレームワークが標準で提供されているわけではない• Go単体でテンプレートをレンダリングするようなフロントエンドの実装は不向き10
活⽤例• Webサーバー・アプリケーション• Goに標準でWebサーバーの機能が提供されている• サーバーレス・アプリケーション• AWS LamdaやGCP Cloud Functionを使ってイベント駆動やHTTPリクエストを受けるアプリケーションに利⽤できる• コマンドラインインターフェース(CLI)→今回はこの例をご紹介• PerlやBashで処理するようなスクリプトとして利⽤する11
CLIライブラリー例• cobra• CLIアプリケーション作成ライブラリー• コマンドでソースコードの⾻組みを⽣成• ⾻組みに機能の説明や処理を実装することでCLIアプリケーションが簡単に作成できるhttps://github.com/spf13/cobra12
Goのインストール -Windows1. Golangダウンロードサイト• https://golang.org/dl/2. ダウンロードサイトより最新バージョンの.msiをダウンロードしインストーラーに従いインストールする• 例) https://dl.google.com/go/go1.XX.XX.windows-amd64.msi3. ログインユーザーのホームフォルダーに「go」フォルダーを作成4. 環境変数の設定• 検索ボックス > 環境変数• Pathに「C:¥Go¥bin;」を追加• GOPATHを作成し「%HOME%¥go」を設定5. コマンドプロンプト上で以下のコマンドでバージョンが確認できたらインストール完了> go versiongo version go1.XX.x widows/amd6413
Goのインストール -macOS1. Golangダウンロードサイト• https://golang.org/dl/2. ダウンロードサイトより最新バージョンの.pkgをダウンロードしインストーラーに従いインストールする• 例) https://dl.google.com/go/go1.XX.XX.darwin-amd64.pkg• ターミナルを開いている場合にはターミナルを再起動する3. 環境変数の設定$ mkdir $HOME/go$ export GOPATH=$HOME/go$ export PATH=$PATH:$GOPATH/bin4. 以下は.bash_profileまたは.bashrcに追記しておくとログイン時に環境変数が設定される$ export GOPATH=$HOME/go$ export PATH=$PATH:$GOPATH/bin5. ターミナル上で以下のコマンドでバージョンが確認できたらインストール完了$ go versiongo version go1.XX.XX darwin/amd6414
Cobraのインストール$ cd $HOME/go/src/github.com// // ライブラリーのインストール$ go get -u github.com/spf13/cobra$ mkdir -p go-sample-cli && cd go-sample-cli$ cobra init --pkg-name github.com//go-sample-cli // 新規コマンド追加$ find .../cmd./cmd/root.go./LICENSE./main.go$ vim main.go15
package mainimport "github.com/kura-lab/go-sample-cli/cmd"func main() {cmd.Execute()}161. mainパッケージの定義2. ライブラリーのインポート3. main関数4. cmdパッケージのExecute関数呼び出しmain.go
サブコマンドの追加$ cobra add hello // 新規サブコマンド追加$ find .../cmd./cmd/hello.go./cmd/root.go./LICENSE./main.go$ vim cmd/root.go$ vim cmd/hello.go./main.go ./cmd/root.go./cmd/ hello.go./cmd/ hoge.go…./cmd/ fuga.go呼び出し元 コマンドの実装サブコマンドの実装17
package cmdimport ("fmt""github.com/spf13/cobra"…省略…)var cfgFile stringvar rootCmd = &cobra.Command{Use: "go-sample-cli",…省略…}func Execute() {if err := rootCmd.Execute(); err != nil {fmt.Println(err)os.Exit(1)}…省略… 181. サブコマンドを含むパッケージの定義2. 複数ライブラリーのインポート3. パッケージの名前空間に変数を定義4. デフォルトのコマンドの構造体を初期化し変数に代⼊root.go5. Excute関数の定義(main関数から呼び出される)
package cmdimport ("fmt""github.com/spf13/cobra")var helloCmd = &cobra.Command{Use: "hello",Short: "A brief description of your command",…省略…Run: func(cmd *cobra.Command, args []string) {fmt.Println(“hello called”)},}func init() {rootCmd.AddCommand(helloCmd)}191. サブコマンドの構造体の初期化と変数への代⼊4. パッケージの初期化(main関数よりも先に実⾏される)5. コマンド本体へサブコマンドを追加hello.go3. サブコマンドで提供する処理を実装する2. 無名関数を構造体に追加
実⾏$ go run main.go hello // バイナリーを⽣成せずに実⾏hello called$ go build // バイナリーを⽣成$ ./go-sample-cli hellohello called20
CLIの利⽤イメージ• オンプレミスアプリケーション• ログの集計・加⼯• アプリケーションの監視• アクセスログ• エラーログ• メール通知• クラウドアプリケーション• ヘルスチェック• Web APIでステータスを確認する• イベント駆動処理• cron、Lambda、Cloud Functionなど21
最後に• Googleの提供するGoをご紹介させていただきました• Goはシンプルな実装になっており、読解性、⽣産性、⾼速性に優れています• 今回ご紹介したCLI以外にもWebサーバー・アプリケーションやサーバレス・アプリケーションも実装できます• デメリットがあるものの、他の⾔語よりも洗練されている部分もあるためエンタープライズの領域においても導⼊を検討してみてはいかがでしょうか• 中級者編以降のご紹介やハンズオンなどのご依頼お待ちしております22
ご清聴ありがとうございました23