JavaScripter が Golang を始める #1

## JavaScripter だって、コンパイルするタイプの言語: 非 script language の言語をやってみたい

みなさんご存知の通り、JavaScript は script language と呼ばれるタイプの言語で、コンパイルを必要とせず、そのままスクリプトがブラウザで処理される。一方、コンパイルが必要な言語には Java や C なんかがある、らしい。詳しくはわからない。

世の人がするというコンパイル、JavaScripter だって書いてみたい。「コンパイルに時間がかかるんですよ〜」とか言ってみたい。Babel や Webpack を使ってするあれは、厳密にはトランスコンパイルというらしい。少し違うらしい。本当のコンパイルをしてみたい。

## C, Java, Scala 系は既存のプレイヤーに勝てなさそうだ
このあたりの言語は古参の強いプレイヤーが多いので、新規参入しても勝てなさそうだ。勝つ必要はないのだが、知識の積み重ねが必要そうなので（あくまでイメージだが）、それよりは新しい言語をやったほうが良さそうだ。

Golang ならまだユーザーは少なさそうだし。


## Go のバーンジョンを管理するために GVM をインストールする

フロントエンドでは NodeJS が中心となる。このバージョンを管理するためにみんな NVM 等のバージョン管理ツールを使っていると思う。(そもそも Docker で開発環境も構築している、という人もいるとは思うけれど)

Go のバージョン管理ツールの代表格は GVM のようだ。まずはこれをインストールする。

https://github.com/moovweb/gvm

書かれているようにターミナルで以下のコマンドを実行する。

```bash
bash < <(curl -s -S -L https://raw.githubusercontent.com/moovweb/gvm/master/binscripts/gvm-installer)
```

その後最新の安定バージョンの GO をインストールする。

```bash
gvm install go1.10.3
```

しかし次のようなエラーが出る。

```
/Users/nakanishi/.gvm/scripts/install: line 84: go: command not found
ERROR: Failed to compile. Check the logs at /Users/nakanishi/.gvm/logs/go-go1.10.3-compile
```

よくよくドキュメントを読むと以下のようにある。


> A Note on Compiling Go 1.5+
Go 1.5+ removed the C compilers from the toolchain and replaced them with one written in Go. Obviously, this creates a bootstrapping problem if you don't already have a working Go install. In order to compile Go 1.5+, make sure Go 1.4 is installed first.

つまり 1.5 以上のバージョンの Go をコンパイルするためには、1.4 をまず入れないといけないと。なるほど。入れる。

```bash
gvm install go1.4 -B
```

で入れる。入れたので最新版を入れる。

```bash
gvm install go1.10.3 -B
```

```bash
gvm list # GVM にインストールされた Go のバージョン一覧を確認する
gvm use go1.10.3 --default # default で使用する Go のバージョンを指定する
go version # どのバージョンの Go が使われているか確認
```

これで go のバージョンが出れば OK。

## おもむろに Goland を起動する

JetBrains 社の IDE である Golang をここで起動する。私はフロント開発時には WebStorm を使っている。気に入っているので Go の開発でも JetBrains 製品を使いたい。

新しいプロジェクトを作成して、プロジェクトのディレクトリ直下に hello.go を作成する。すると、`package プロジェクト名` というコードがデフォルトで作成される。しかし、これだとうまく動かないので、package main と変えて、よくあるサンプルコードと同じにしてコードを書いていく。(package main としない方法もあるのだとは思うが、とりあえず動かす)

例によってハローワールド。

https://tour.golang.org/welcome/1

```go
package main

import "fmt"

func main() {
	fmt.Println("hello world")
}
```

ここで JSer に注意したいのは、

1. `import "fmt"` と書いて保存すると、その行が即削除される。なぜなら Go のフォーマッティング機能が作動して、使っていない import したものを削除するから。import の部分は書かずに、fmt.Println() を書いてしまおう。すると、勝手に import までしてくれる。
2. `''` は文字列には使えないようだ。文字列を表すためには`""`を使おう。

特に 1 に結構ハマった。GOPATH とかの設定がおかしいのかと思ってインストールし直したりもした。結論からいえば、Go のフォーマッティング機能が気を効かせて使っていないモジュールを削除してくれていたのだ！一言声をかけてほしい！！！

2 については、今 JS の世界では `''` を使うのが標準化されているが、Go においては文字列を表すためには `""`でないとダメなようだ。詳細はわからない。

すると Golang では func main() の左側に緑色の再生マークがでるはずだ。これをクリックして、実行できる。

<img width="370" alt="Screen Shot 2018-08-12 at 7.55.33 PM.png" src="https://qiita-image-store.s3.amazonaws.com/0/240885/b90ab2e7-d911-bb38-fd1a-402584be6562.png">

ターミナルからは以下。

```
go run hello.go
```

スターティング Go 言語(http://amzn.asia/8bjnTFJ) によれば、これによってビルドもした上で実行してくれているらしいが、それを隠蔽したコマンドらしい。とにかくビルドはしていると。

## Go における package について
どうやら Go においては、1 ファイルが 1 package を作るためにあるようだ。冒頭の package main という宣言は、このファイルは main という名前の package を定義しますよという宣言のようだ。

## package main の func main() がエントリーポイントになる

同じくスターティング Go 曰く、main package の中の func main() がエントリーポイントになるとのこと。NodeJS アプリケーションのエントリーポイントと同じですね。だから main 以外のパッケージ名、ファンクション名にすると実行できなかったわけです。

## 初めてのビルド

ではコンパイルして実行ファイルを作成します。実行ファイルというは、詳しくは説明できませんが、ターミナルからシェルスクリプトのように実行できるやつ。

例えばコンパイルで作成した Go の hello という名前を持つ実行ファイルは、ターミナルから以下のコマンドを実行することで実行できる。

```bash
./hello
```

これって JSer にとっては驚きではないだろうか。当たり前だが JavaScript はブラウザでしか動かない。もちろん NodeJS はブラウザの外でも動くけれど、Node がある環境でしか動かない。実行ファイルというのはそうではなくて、普通に OS が実行できるファイルだ(と思う)

ちらっと Go に関する記述を読む限り、Win でも Mac でも Linux でも普通にこの実行ファイルは動くらしい。OS を超えて実行できるようにするというのは結構面倒なイメージだが、Golang なら簡単ということだろうか。

ということで buid する

```bash
go build -o hello hello.go
# go build -o 出力するときのファイル名 ビルドの対象ファイル 
```

## 学習リソース

学習のために以下の書籍を購入した。

- Tour of Go (https://tour.golang.org) ウェブ上のテキスト。文法を学ぶのにはこれで事足りそうだ。
- スターティング Go 言語 (http://amzn.asia/8bjnTFJ) 同じくシンタックスの学習。
- Go言語によるWebアプリケーション開発 (http://amzn.asia/7GuRB9z) ウェブエンジニアなので具体的な Web App の作り方は参考になりそうだ。
- Go言語でつくるインタプリタ (http://amzn.asia/fQq1emz) 実はこれが大きな目的。インタプリタを理解するのはコンピュータサイエンスにとって重要だと思う。コンピューターサイエンスの学位をとってシリコンバレーに行きたいので、これを実装するのが Go を学習する一つの目的。

上から順番に基礎向け。

ということで #2 も書いていきます。