「みんなのGo言語 現場で使える実践テクニック」を読んだ感想

# 「みんなのGo言語 現場で使える実践テクニック」を読んだ感想

私のGo言語歴は1年くらいで、仕事のちょっとしたツールや趣味でちょっとしたOSSライブラリを書いたりしてます。

以前Twitterでおすすめされていた[みんなのGo言語](https://www.amazon.co.jp/%E3%81%BF%E3%82%93%E3%81%AA%E3%81%AEGo%E8%A8%80%E8%AA%9E%E3%80%90%E7%8F%BE%E5%A0%B4%E3%81%A7%E4%BD%BF%E3%81%88%E3%82%8B%E5%AE%9F%E8%B7%B5%E3%83%86%E3%82%AF%E3%83%8B%E3%83%83%E3%82%AF%E3%80%91-%E6%9D%BE%E6%9C%A8%E9%9B%85%E5%B9%B8/dp/477418392X/ref=sr_1_1?ie=UTF8&qid=1510929915&sr=8-1&keywords=%E3%81%BF%E3%82%93%E3%81%AA%E3%81%AEgo%E8%A8%80%E8%AA%9E&dpID=61EL3Dc95dL&preST=_SY291_BO1,204,203,200_QL40_&dpSrc=srch)がなかなか面白そうな内容だったので、購入。
とてもいい内容だったのでより深く理解するために、また、周りにGo言語の良さを布教するために記事にしてみました。


## 全体的な内容

内容としては次のような感じです。

- 初級者〜中級者向け
- Goを業務で利用している筆者陣が「これは知っておくべき」「これはハマりやすいので注意」「これは便利」といった事柄を解説
- Go言語の得意な部分/苦手な部分の説明
- Tipsや便利な使い方の紹介
- おすすめライブラリの紹介

## 1章 Goによるチーム開発のはじめ方とコードを書く上での心得

このへんはGo言語に触れたことがある人ならば理解は容易だと思います。

- 開発環境の構築と`go get`
  初心者向けの本のお約束ですね。

- ディレクトリ構成の例
  自分でプロジェクトを作成する際に大いに参考にさせていただいております。

- エディタの話
  vim、Emacs、IntelliJ IDEA、Atom等が主流のようです。
  私は[neovim](https://neovim.io/) + [vim-go](https://github.com/fatih/vim-go)な環境で書いています。

- gofmt, goimports, govet, golint
  周辺ツールも公式のがいろいろあります。
  vim-goならvimから呼び出したり自動でチェックできるのでさらに便利です。

- Goらしいコードとは
  個人的にはここの*"Goに入ってはGoに従え"*というフレーズがツボでした。



## 2章 マルチプラットフォームで動作する社内ツールの作り方

- Goで社内ツールを作る理由  
  実行可能なバイナリにビルドできる点が大きいですよね、というお話。
- OS差異吸収
  私はLinuxしか使わないし、**この世からWindowsを滅ぼしたい派**の人間なので、他のOSなんて気にしません！
  とはいえ、他OS向けにバイナリをビルドできる点はGo言語の主な魅力に一つですね。

- シングルバイナリの良さ
  ここで紹介されている[go-bindata](https://github.com/jteeuwen/go-bindata)や[go-assets](https://github.com/jessevdk/go-assets)は私もちょくちょく使ってます。

- 設定ファイル
  近年の主流はINI, JSON, YAML, TOMLですが、個人的にはYAML推しです。

## 3章 実用的なアプリケーションを作るために
- flagパッケージ
  4章で後述します。

- os/execパッケージ
  個人的には外部コマンド呼び出しは極力使いたくないですが、無いと不便な時もあります。

- その他
  この章では、他にも利用頻度が高いテクニックについていくつか記述があります。
  - 入出力/バッファリング
  - 乱数
  - バージョニング

## 4章 コマンドラインツールを作る

この章ではコマンドラインツールの作成に役立つtipsが紹介されています。  
コマンドラインツールはGo言語の入門にとても適していると思うので、この章を参考に何か簡単なツールを作ってみることをおすすめします。

- Go言語で作る理由
  - 配布のしやすさ
  - 複数プラットフォームへの対応のしやすさ
  - パフォーマンス

  個人的に複数プラットフォームへの対応のしやすさが一番ですね。
  職場にはwindowsユーザーも多いので。

- リポジトリ構成
  バイナリをメインの成果物にするか、ライブラリをメインの成果物にするかで構成は変えるべきだと思います。

- flagパッケージ
  flagパッケージを利用することで、簡単にオプションを定義できます。
  また、usageの出力も簡潔に書くことができます。

- サブコマンドをもつCLIツール
  引数が多くなる場合はサブコマンドを持たせる設計が一般的です。
  自分で一から書くこともできますが、次のサードパーティ製パッケージを利用すると楽に書けます。
  - urfave/cli
  - spf13/cobra
  - docopt/docopt.go
  - michelh/cli
  - google/subcommands

- 使いやすいツール
  - ステータスコード
  - 標準出力とエラー出力
  - エラーメッセージ

## 5章 The Dark Arts Of Reflection

Go言語は静的型付け言語ですが、時には動的な型を決定する必要があります。  
そのような場合に役立つテクニックを紹介しています。

- refrectパッケージ  
  このパッケージを使わないことには始まりませんね。

ライブラリを開発した際、より汎用的なインターフェースに設計する際は必須のテクニックではないかと思っています。
(ちにみに、[こんな](https://github.com/reireias/go-json-server)ライブラリです。)

## 6章 Goのテストに関するツールセット

- UT用のtestingパッケージ
  標準パッケージにテスト用のtestingパッケージがあります。
  testingパッケージをインポートし、funcを書くことでテストメソッドを記述できます。

- ベンチマークも可能
  funcの名前をBenchmarkから始めることで、ベンチマーク用メソッドを記述できます。
  `go test -bench`コマンドでこれらのベンチマークを実行することができます。

githubで開発している場合はTravis CIとの組み合わせが導入も容易で鉄板ですね。
ベンチマークはまだ試したことがないので、いつか試してみようと思います。


## まとめ

私としては、Go言語は静的型付け言語な上、文法には独特な部分があり、PythonやRuby等の一般的に入門しやすいと言われている言語と比べて、敷居が高くみられがちな印象です。

ですが、**シングルバイナリ**、**マルチプラットフォーム**、**高パフォーマンス**、**並列処理**等、Go言語ならではの魅力がたくさんあります。
また、ライブラリや周辺ツールも充実しており、環境構築が容易な点も人気の理由の一つだと思います。

(ライブラリなんかは[awesome-go](https://github.com/avelino/awesome-go)あたりをいつも参考に探しています。)

業務での採用はなかなか先になりそうですが、周辺ツールやOSS等では積極的にGo言語で書いていこうと考えています。