Goチートシート（個人メモ）

取り敢えず形だけ（ごめんなさい）。
随時更新します。

# 環境設定

Macならbrewで入れればいい

```shell-session
$ brew install go
```

# ビルド・実行

## クロスコンパイル

# 基本文法

## ポインタ
参考: 

[Goでxxxのポインタを取っているプログラムはだいたい全部間違っている](http://qiita.com/ruiu/items/e60aa707e16f8f6dccd8)

## 標準入力・標準出力

### 標準入力
[Go 言語で標準入力から読み込む競技プログラミングのアレ --- 改訂第二版](http://qiita.com/tnoda_/items/b503a72eac82862d30c6)を参照

#### fmt.Scan

```go
var a int
fmt.Scan(&a)
```

#### bufio.Scanner

```go
var sc = bufio.NewScanner(os.Stdin)
var line string
if sc.Scan() {
    line = sc.Text()
}
```

### 標準出力
```go
fmt.Println("Hello world")
```

## 関数

### 無名関数
### クロージャ

## 配列

### 宣言

```go
var a [5]string
```

サイズを指定する

### 初期化

```go
var array [6]int = [6]int{1, 2, 3, 4, 5, 6}

// 省略
array := [6]int{1, 2, 3, 4, 5, 6}
```

## スライス

### 宣言

```go
var a []int
```

## 構造体
## for

```go
for i := 0; i < 10; i++ {
   fmt.Println(i)
}
```

```go
for _, e := range array {
    fmt.Println(e)
}
```

### while
## map

### 宣言

```go 
var m map[key_type]value_type
```

###  初期化
```go
m = make(map[key_type]value_type)
```

### 要素伴った初期化

```go
var m = map[key_type]val_type{
	key1: val1,
	key2: val2,
}
```

### 挿入

```go
m[key] = val
```

### 要素の取得

```go
val = m[key]
```

### 削除

```go
delete(m, key)
```

### 存在するかの確認

```go
val, ok = m[key]
```

### for

```go
for k, v := range m {
    fmt.Println(m, v)
}
```

## 三項演算子
ないので諦める（参考: [Goには三項演算子a?b:cはない ―― 代わりの書き方](http://qiita.com/ruiu/items/61236f09b3469a679eb9)）
特にIntのMin/Maxがないので、そこで少し書き方が冗長になる。

## 文字列の処理

### sprintf

```go
fmt.Sprintf("id: %d, name: %s\n", i, name)
```

### 文字列の分割

```go
s := strings.Split("ABC,DEF", ",") // return []string
```

## チャネル
[Visualizing Concurrency in Go](http://divan.github.io/posts/go_concurrency_visualize/)

## エラーハンドリング

### 新しいエラーを投げる

```go
return nil, errors.New("Faield to get Document from response")
```

# logging

# Godoc
[Godoc](https://www.google.co.jp/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&ved=0ahUKEwiyn-rTzo7NAhUiKqYKHWK-DWcQFggbMAA&url=https%3A%2F%2Fgolang.org%2Fcmd%2Fgodoc%2F&usg=AFQjCNEPawjmrVTt7n4GhXorlHDijnc2ig&sig2=OddV2-Tsmj5m44FjshmZcw&bvm=bv.123664746,d.dGY&cad=rja)

で検索すれば登録される（？）

バッジはこのToolsリンクから

<img width="793" alt="スクリーンショット_2016-06-04_23_52_05.png" src="https://qiita-image-store.s3.amazonaws.com/0/35293/1f36cce7-d50d-7677-9ed5-10bb0197f29e.png">

# CLI

## docopt

# Travis CI
[Building a Go Project](https://docs.travis-ci.com/user/languages/go) （まだ確認してないがgodepサポートとかもあるらしい）

```.travis.yml``` を直下におく。

```.travis.yml``` の例:

```yaml
language: go

go:
  - 1.5
  - tip

install:
  - go get github.com/... (or use Makefile)

scripts:
  - go test -v .
```

```.travis.yml``` をpushしたら [Travis CI](https://travis-ci.org/) で設定をする。

## Coveralls
See [Go + Travis CI + Coveralls でCI環境を作る - Qiita](http://qiita.com/dmnlk/items/3fb4e0abb98e39fee275)

```yaml
language: go

go:
  - 1.5
  - tip

before_install:
  - go get github.com/axw/gocov/gocov
  - go get github.com/mattn/goveralls
  - if ! go get code.google.com/p/go.tools/cmd/cover; then go get golang.org/x/tools/cmd/cover; fi

script:
    - $HOME/gopath/bin/goveralls -repotoken $COVERALLS_TOKEN
env:
  global:
    secure: <COVERALLS_TOKEN>
```

### TOKENの作り方

TOKENをCoverallsのサイトからとってきて

```sh
travis encrypt COVERALLS_TOKEN=<TOKEN>
```

もし ```travis``` コマンドが入ってなければ

```sh
$ sudo gem install travis
```

# テスト
> Go は、 assert やその他テストを構造化する仕組みなどを標準で提供しない代わりに、最小の API と十分なコマンドを提供することでテストを限りなく「ただの Go プログラム」で書けるようにしています。（[Go の Test に対する考え方](http://qiita.com/Jxck_/items/8717a5982547cfa54ebc)）

## 手順
1. ファイル ```bar.go``` に対するテストとして ```bar_test.go```を同じフォルダに用意
2. テストするパッケージを ```bar``` として、 パッケージ名を ```bar_test``` とする
3. ```testing``` パッケージをimportする
4. 次のようにテストを書く

```go
package bar_test

import "testing"

func TestSomeFunc(t *testing.T) {
    actual := "a"
    expected := "b"
    if actual != expected {
        t.Errorf("\ngot  %v\nwant %v", actual, expected)
    }
}
```

最後に ```$ go test``` を実行して結果をみる。

## go testのオプション

- ```-v```: より詳細に結果を見る

## その他
最初に初期化が必要なものは ```init()```の中で初期化ができる。

## TIPS

### MapやSliceの比較

```go
if !reflect.DeepEqual(expected, actual) {
    t.Errorf("\ngot  %v\nwant %v", actual, expected)
}
```
# GAE

# I/O

## Json
[GoDoc: encoding/json](https://golang.org/pkg/encoding/json/#Unmarshal)

```go
import "encoding/json"
```

### Marshal

```go
user := User{
	Id:     0,
	Name:   "sotetsuk",
	Friends: []string{"pikachu", "gopher"},
}
b, err := json.Marshal(user) // []byte
```

### Unmarshal

```go
var user User
err := json.Unmarshal(userBytes, user)
```

## Toml

# 正規表現
[逆引きGolang (正規表現)](http://ashitani.jp/golangtips/tips_regexp.html#regexp_Numbering)

```go
import "regexp"
```

### コンパイル

```Compile``` or ```MustCompile``` でコンパイルする。MustCompileはコンパイルに失敗するとpanicを返す。
ダブルクォーテーションのエスケープ等が面倒なので、バッククォーテーションで囲むのが良い。

```go
r := regexp.MustCompile(`expr`)
```

### マッチした文字列を全て抜き出して配列へ格納する

```go
s := ""
r := regexp.MustCompile(``)
fmt.Println(r.FindAllStringSubmatch(s, -1))
```

# パッケージ

## バッジリスト
こんな感じにバッチがつく

<img width="567" alt="スクリーンショット 2016-06-05 2.22.19.png" src="https://qiita-image-store.s3.amazonaws.com/0/35293/e0a1acae-8305-af79-7173-e8dd115e9916.png">

- Godoc: GodocページのToolsリンクから
- TravisCI: Travisのサイトから
- Coveralls: Coverallsのサイトから
- Version: [Version Badge](https://badge.fury.io/)から
- License: [shields.io](http://shields.io/)から

Versionのバッジは反映を早くするためにWebhookを設定するのが良い。

# 依存管理

## GoDep

```$ godeq save``` とか色々書く

# クロスコンパイル

[github.com/mitchellh/gox](https://github.com/mitchellh/gox)を使う。

```$ gox``` と打つだけでクロスコンパイルを並列で実行してくれる。

# ライブラリ一覧

- [github.com/puerkitobio/goquery](https://github.com/puerkitobio/goquery): スクレイピング
- [github.com/PuerkitoBio/gocrawl](https://github.com/PuerkitoBio/gocrawl): クローリング
- [github.com/sirupsen/logrus](https://github.com/sirupsen/logrus): ロギングライブラリ
- [github.com/k0kubun/pp](https://github.com/k0kubun/pp): pretty print

# 参考文献
- [A Tour of Go](https://go-tour-jp.appspot.com/)
- [Go 言語に関するブックマーク - Qiita](http://qiita.com/spiegel-im-spiegel/items/98d49ac456485b007a15)
- [Visualizing Concurrency in Go](http://divan.github.io/posts/go_concurrency_visualize/)
- [逆引きGolang (正規表現)](http://ashitani.jp/golangtips/tips_regexp.html#regexp_Numbering)
- [Go の Test に対する考え方](http://qiita.com/Jxck_/items/8717a5982547cfa54ebc)