Go事始め

#Go始めるきっかけ
次の案件にむけて　Goで開発する可能性がある事と
Goに対して不満を抱えているなら　まずは相手を知る必要があると思ったから

#Go経歴
むかし DevOpsのBOTとして少しだけさわった
https://github.com/YukiMiyatake/chaps

Slack上で動くBOTだ 
AWSを操作可能
一応 機能を拡張できるようプラグインにしている

ただ　コードは適当。まだ初心者なので

#Go インストール
初心者がGoをちょっとずつ勉強していくよ

##インストール
私は最近はWindows10 Pro 64bitとDockerを使っての開発の可能性を探ってるので
まずは　この環境で構築するよ
Golandも手に入れたのでGolandも使う
ので　WindowsネイティブでGolandを使って開発する環境
WSLを使ってGoを開発する環境
Dockerを使って開発する環境
の3つを両立する

###Docker
https://qiita.com/YukiMiyatake/items/73c7d6c4f2c9739ebe60
にまとめてあるので。
しかも GolandだとDockerでの開発にも対応しているようで期待

###WSL
多分最難関かなと思う

####インストール
まず apt-getでGoをインストールしようと思ったが

```bash
$ sudo apt-get install gccgo-go
```

だととても古いバージョンが入る

```bash
$ sudo apt-get install golang-go
```

でも古く　ソースから作ってもいいけど　パッケージの最新をみたら

```bash
$ dpkg -l | go
```

golang-1.10 だったので妥協

```bash
$ sudo apt-get install golang-1.10
```
####パス
Goはパスの考え方が少し面倒
どうやら サンドボックスという考え方？のようで
全てのもの（開発用コード）も GOROOT　以下にサンドボックスするという仕様のようだ
（ GOPAHと GOROOTがあって ややこしいけど）
これは Goのバージョンごとに GOROOTを作り その中で開発すればバージョン問題を閉じれる事
と　Google的には最高なんだろうけど
ソースコードは まとめている私のポリシーには面倒だが　従うしかない
 GOROOT内部に Goのバイナリ、ライブラリ（.a）、ビルトインライブラリコード、外部コード、自分のコード　と全部入る
 GOROOT（正確には GOPATH）の外のコードは ビルド不可能という仕様だから 自分のコードも中に入れなければいけない。
一応 GOPATHを複数指定し、外のディレクトリもビルド可能のようだが
初心者なので　サンドボックスに入れることにする
デフォルトだと ~/go になる

ただし、Windowsともコードは共有したいので　ちょっとかえる

GOROOTは 基本的にしていしなくてよくなったので指定しない
WSLのホームディレクトリは　Windowsからアクセスしにくい場所なのでかえる
 GOPATHで /mnt/c/devel/go-1.10 を指定し、ここで開発することにした
具体的には開発コードは /mnt/c/devel/go-1.10/src/github.com/YukiMiyatake/プロジェクト名
というフォルダになり、gitもここを作業ディレクトリにする
.bashrcには下記のようにかいた

```bash
export GOPATH=/mnt/c/devel/go-1.10$
export PATH=/usr/lib/go-1.10/bin:$PATH$
```

/usr/lib/go-1.10 は、apt-getでインストールされたディレクトリだ
ちなみに 自動的に GOPATHはこのディレクトリが指定されている

これで /mnt/c/devel/go-1.10/src 以下でgoファイルをビルドすると動いた

ちなみに ビルドをするとライブラリを探しに行くが
 GOROOT、 GOPATH  を探してくれるようで、存在しない場合は GOPATHにダウンロードしてくれる


###Windows
####インストール
WSLでひよって 10.4と1つ古いバージョンをインストールしたので　それに合わせる
https://golang.org/dl/
より 10.4の amd64を選びインストールする
デフォルトでは C:Go にインストールされるので
C:\Lib\go-1.10\　に変更した

####パス設定
パスの設定は上記WSLにあわせる

コントロールパネル 環境変数の設定にて
GOPATHにWSLと同じソースディレクトリ C:\devel\go-1.10
PATHにインストールしたパス c:\lib\go-1.10\bin

GOPATHは同じディレクトリにしても ライブラリのビルドはシステムごとにわかれているので
おそらくOKだろう

ただしWindowsでは現在 Pluginが対応していない。Shell Executeも動かなかったので
基本的には あまりWindows版は使わないかもしれない

#Goland
JetBrains社の Go言語エディタ
インストールすると 32bitと64bitが入る。
が　試したかんじでは どちらをインストールしても 上記の環境変数に指定したGoを見るような気がする
（32bitGolandを起動すれば32bitのGoビルドになるわけではなさそう）
JetBrains社のエディタはJavaで作られていて 単にそのエディタの JREのビットの可能性が高い
いちおう32ビットエディタを動かす手順だが、JREは64bitしかついてないので 32bitのJREは自分でインストールしなければならない

ビルド、デバッグ、リファクタリングなど出来、便利だと思うのでこれから使っていこうと思う
（これまではVSCodeを使い　それでも十分満足ではあるが）

#他の言語世界からきて戸惑ったポイント
##構文
セミコロンが不要言語
ifなどの制御公文に()が不要
whileがない　かわりにfor
C言語の構文にたいして　ことごとく逆である
class構文がない
慣れる以外ない

```cpp
int n;

int calc( flot f )

int(*fn)(float);

void clazz::var(int);

```

```go
var n int

func calc(float f) int

var fn func(float) int

func(c clazz) var(int);

```


##パッケージ
全てのファイルにはパッケージ名が必要（と思われる
mainパッケージだけは特別な名前で、エントリポイントはここのmain() になる
そのため 1つのプロジェクトに mainは1個しか置けない

###import
パッケージをimportできる
import時に _を指定すると省略、.を指定するとネームスペースがグローバルに、別名をかくと別名でアクセスできる
など、いろいろなオプションがある

###ディレクトリ
同じディレクトリには同じ名前のパッケージのソースファイルしか置けない
同じパッケージ名なら同じディレクトリに置くことが出来る
ただし　語尾に _test.go がつくファイルはテストコードなのでパッケージが異なってもOK

###条件付きコンパイル
よくあるコンパイル定数

```cpp
#define HOGE

#ifdef HOGE
#endif
```

は使えない。代わりにファイルの先頭に

```go
// +build hoge
```

とオプションをつける。
ifdefとちがい、ファイル単位でしか指定できなく不便
値の定義は ビルド時に -tags=hoge  とする。ビルド時しかフラグをセットできない
比較は フラグがセットされているかされてないかの2値

###クラスがない
クラスはないが　レシーバーという構文で　似たようなことはできる
いわゆる C言語等でやる thisポインタを明示的に渡すあれと同じ考え方
ただし thisポインタにあたるものは 引数ではなく　レシーバという特別な引数で指定できる