なかなか入門できなかった自分のために、Goの入門以前レベルの記事が欲しいなと思いました。
流行に敏感なGopher1の諸賢から見るとめちゃくちゃ言っている可能性もありますが、自分なりにこれならわかりやすいんじゃないかな〜という目線でまとめてみています。
なお、記事執筆時点でGoのstableバージョンは1.12.1ですのでその想定で進めます。
想定読者
- Goを始めようとしたけどずっと分からなくて何度も挫折している
- 出来るだけシンプルな構成でGoを始めたい
- GoでAPIを作りたいけどよく分からない
- Ginって噂は聞くけどまだよく分からない
- GoでAPIが動けばいい。逆にいうとあんまり高度なことを最初から書かないでほしい
あまり想定していない読者
- 非Macな方
- Goの文法が知りたい
- A Tour of Go ならリアルタイムで動かせてとてもわかりやすいです。
- Goのアーキテクチャとかを学びたい
- 知見不足で良い記事がまだ分からないので参考資料割愛。クリーンアーキテクチャとかで記事が大変多くあるようです
- https://github.com/golang-standards/project-layout 噂によるとこの辺が参考になるらしい
- Ginに入門したい
- https://qiita.com/Anharu/items/ce644c521a4d52fafb7e この方の記事とかわかりやすそう
- Goのお作法を学びたい
- 噂によるとこれがデファクトスタンダードのようです。
- CodeReviewComments
- 和訳: #golang CodeReviewComments 日本語翻訳
- Effective Go とかいう経典みたいなものがあるとのこと
- Goのよく使われるモジュールとか知りたい
- 勉強中なので待ってほしい
disclaimer
書いた人は基本はRubyist、ちょっとSwiftも書く、みたいな人です。
そんな目線で書かれているところが随所にあります。
環境構築とかサンプルコードの段階で複雑すぎると凹んじゃうタイプなので、自分でも心が折れないような粒度にしようと思いました。
Goの特徴について
まだよく分からないんですけど、以下のような特徴があるらしいです。
- 静的型付け言語
- 型が強制されるっていいですよね。僕は好きです。メリットとしては、コンパイル時点で不適切な処理を見つけ出しやすくなるというのがあります。静的解析や自動テスト、Linterなどと相性がいいという噂です。
- コンパイル型言語
- インタプリタ的に動かすこともできます(内部的にどっちなのかはまだ調べてないです)が、コンパイルしてシングルバイナリ実行ファイルに落とし込むことができます。
- 依存しているライブラリなどがほとんどなく、様々な実行環境で安心して動かせるということでポータビリティが高い、なんて言われたりしているようです。
- シンプルな言語仕様
- Goはあまり多くの言語仕様をサポートしていないらしいです。黒魔術みたいなことよりも、多少冗長でも(ここは誤解があるかも)シンプルで素直な記述をすることを好むとのこと。
- 並列処理を言語レベルでサポート
- differとかContextとかそんな単語を噂に聞きます(まだよくわかってない)
Goをインストールする
この記事ではHomebrewを使います。
Homebrewが入っていない人は・・・ Homebrew 公式サイトからいい感じによろしくお願いします。
入っているか自信がないあなたは、terminalでおもむろに brew --version
と打ちましょう。バージョン情報が返ってくれば多分大丈夫です。
さて、以下のコマンドをterminal上で実行することでGoをインストールできます。
その時点での最新の安定版がインストールできるはず。
brew install go --HEAD
go version
を実行して、
go version go1.12.1 darwin/amd64
のような結果を受け取れれば成功です。
バージョン管理がしたい人はgvmがいいらしい
こちらの記事などが参考になるかも。
僕は噂に聞く Go Modules が動いてくれればなんでも良かったので今回はスルーしています。
https://qiita.com/keiichi-hikita/items/5a798b35867c057d16d1
Goはdockerとかと組み合わせて使うことが多くてローカル環境でバージョン管理する必要性をあまり感じない、なんて話も時たま聞きます。
Goを動かす
Goのコードを書きましょう。
最初に呼び出されるファイルはmain.goという名前をつけることが多いようです。
package main
import "fmt"
func main() {
fmt.Println("Hello, 世界")
}
A Tour of Go からそのまま拝借しています。
動かすときは、
go run main.go
を実行します。
"Hello, 世界"
という風にterminalの標準出力に出てくれば成功です。
Goをコンパイルする
Goの特徴について、のところで言及した通り、シングルバイナリの実行ファイルにすることができます。すごい便利そう。
やり方ですが、非常に簡単です。
go build main.go
とすると、同じディレクトリに
main
というファイルが生成されます。これで完了です。
コンパイルしたファイルを動かす
この生成されたファイルを実行するときは、
./main
とすることで実行可能です。実行ファイルなので、ファイルを呼び出すだけで動くんですね。
ちなみに、単純に main
とやると実行ファイルの呼び出しではなくbashのコマンド呼び出しと解釈されるみたいで、僕の環境では -bash: main: command not found
となってしまってうまく動きませんでした。
ginを導入する
さて、ginを導入していきたいわけですが、ginは外部のパッケージなので使える状態にする必要があります。
そのために、 Go Modules
というGoの公式のパッケージ管理機能を使っていきましょう。
Go Modulesを準備する
では、つい最近Go標準パッケージ管理ツールとなったGo Modulesを使ってやっていきます。
Go Modulesを使うためにいくつか準備を進めましょう。
まず、Go Modulesを使うためには、
GO111MODULE=on
という指定が環境変数に追加されている必要があります。
環境変数以外のやり方もあるのかもしれませんが、とりあえずこれは動きます。動きました。
~/.bash_profile
または ~/.bashrc
の末尾あたりに、
export GOPATH=$HOME/go
export GO111MODULE=on
この二つの記述を追記しましょう。いいですか、追記ですからね。 2
ここまでできたら、追記した方のファイル(今回は ~/.bash_profile
とします)を読み込みます。
以下のコマンドをterminalで実行しましょう。
source ~/.bash_profile
うまくいってるかは、
printenv | grep GOPATH
printenv | grep GO111MODULE
とかで確認できます。
環境変数の設定ができたら、パッケージ依存関係管理をするための初期化を行います。
mkdir -p ~/go/src/github.com/gotest
(※ gotest
の部分は任意の名前です。 path も src 配下なら必須とかではないかも)
みたいな感じでディレクトリを作って、
cd ~/go/src/github.com/gotest
3
して今回の開発用ディレクトリに移動しましょう。今回はここを実験場とします。
このディレクトリで、
go mod init
を実行します。
ls
したときに、 go.mod
というファイルが作られていれば準備完了です。
ginをインストールして動かす
いよいよ gin を使う main.go を書いていきましょう。こんな感じ。動けばok。
githubの公式リポジトリ、 gin-gonic/gin のサンプルそのままです。
package main
import "github.com/gin-gonic/gin"
func main() {
r := gin.Default()
r.GET("/ping", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "pong",
})
})
r.Run() // listen and serve on 0.0.0.0:8080
}
このファイルができたら、同じく ~/go/src/github.com/gotest
ディレクトリで、
go run main.go
をしましょう。
Go Modulesが依存関係を解決して、必要なパッケージをインストールしてくれるので、しばらく待てばプロセスが立ち上がります。プロセスが立ち上がったら、 localhost:8080/ping
にアクセスしましょう。
{
"message": "pong"
}
というAPIレスポンスが取得できるはずです。
個人的にすごいなーと思うのは、
import "github.com/gin-gonic/gin"
と書いただけでgithubから依存関係を解決してくれちゃうところですね。github上のリポジトリを使いたいときにものすごく素直に使える感じがしてとても好きです。
go build main.go
すれば、依存パッケージも含めてビルドしてくれるので、先ほど同様
./main
で localhost:8080 が立ち上がります。
それでは、良い go/gin のAPI開発ライフをお送りください。
オマケ: ところで export GOPATH=$HOME/go
ってなに?
環境変数 $GOPATH
というのを指定する記述です。依存関係を管理したりいろんなところで使うようです。
今回だと、 $HOME/go
つまり ~/go
にしましたが、 $HOME/.go
とかにする人もいるみたいです。
この $GOPATH
にしたがって、 $GOPATH/pkg/
ディレクトリ配下に依存関係にあるパッケージがダウンロードされます。
そのうちやりたい
gormの使い方とか、dockerでどうやって動かすかとか、k8sにどうやってあげるかとか、そっち方面の勉強中なのでいつかまとめられたらいいなあ。と思いつつ終わりです。
みんなも幸せなGopherライフを送りましょう!
-
GopherくんというGoの愛されマスコットになぞらえて、Goを書く人もGopherと呼ぶらしい ↩
-
僕はここで
.bash_profile
触るのもbashでファイルいじるのも久しぶりなのに雑にやろうとしてecho `export GOPATH=$HOME/go` > ~/.bash_profile
とかやって設定吹き飛ばしました。一瞬マジでヤバいかと思った。(普段使う機能は復旧できました)。なんか別のところで似たような記述を見て「えーこれ追記してくれるんだ〜」と思ってめっちゃ雑にやったんですけど末尾追記は>>
であって>
ではダメです。>
でやると上書きで吹き飛びます。つまりecho `export GOPATH=$HOME/go` >> ~/.bash_profile
が正しかった。。 ↩ -
$GOPATH/src/github.com/USERNAME/REPONAME という形式でディレクトリを掘るのが慣習的に好まれているようなので、特にこだわりがない方はそれに倣うと良さそうです。 ↩