A Tour of GoのExerciseをやってみた(Concurrencyの手前まで)

A Tour of GoのExerciseをConcurrencyの手前まで一通りやってみたので、
自分の書いたコードと詰まったポイントなどを補足しながら記事を書いてみました。

同じくGo初学者の参考になれば幸いです！
Concurrencyも後ほど実施予定です。。

## Exercise: Loops and Functions

問題は以下。

https://go-tour-jp.appspot.com/flowcontrol/8

ニュートン法を用いた近似の問題です。
問題文のここが難解ですが、`z -= (z*z - x) / (2*z)`
これは放物線に対して接線を引いて近似をしています。

[ニュートン法のwikipedia](https://ja.wikipedia.org/wiki/%E3%83%8B%E3%83%A5%E3%83%BC%E3%83%88%E3%83%B3%E6%B3%95)の図が分かりやすいかと思います。

最初はニュートン法で10回近似するプログラムを書きます。
`for i:=0; i<10; i++`
みたいな感じで10回ループを書いてあげればできると思います。

次に以下対応します。

- 変化が僅かになったらループを停止させる
- ループ回数を求める
- 標準ライブラリの`math.Sqrt`との差分を求める

コードは以下です。

https://github.com/okaponta/go-practice/blob/master/tour/tour2/exercise-loops-and-functions.go

個人的に詰まったポイントです。

 - 値が僅かに変化する部分で`0`と比較してしまった。
    - 出力した結果、差分としてとても小さい値が出力されたので(9.66e-17)、e-15と比較した
 - 差分の絶対値を比較しなきゃいけないのに気づかなかった。
    - 負の数が差分ででてきたときに問答無用でループを抜けてしまった

## Exercise: Slices

問題は以下。

https://go-tour-jp.appspot.com/moretypes/18

SliceのSliceを作る問題です。

コードは以下です。

https://github.com/okaponta/go-practice/blob/master/tour/tour3/exercise-slices/exercise-slices.go

個人的に詰まったポイントです。(ローカルだとimportできないので実行できません、この問題はplayground上で実行しました。)

 - そもそも問題文を理解するのにちょっと時間がかかった
 - makeの生成するtypeで、二次元配列を宣言する方法がわからなかった
 - uintの変換に詰まった
 - uint(dx)はuint8型にできてもuint(x+y)はuint8型にならない

## Exercise: Maps

問題は以下。

https://go-tour-jp.appspot.com/moretypes/23

mapの使い方に関する問題です、これも問題文がちょっと分かりにくい・・・
とりあえずplaygroundで一回実行すればやりたいことがわかるかも。

コードは以下です。

https://github.com/okaponta/go-practice/blob/master/tour/tour3/exercise-maps/exercise-maps.go

個人的に詰まったポイントです。(こちらもplayground上で実行しました。)

 - 使わない変数は`_`で無視しないとコンパイルできない
 - `strings`って標準ライブラリがあること。`string`って最初読んでで(?)ってなってました。

## Exercise: Fibonacci closure

問題は以下。

https://go-tour-jp.appspot.com/moretypes/26

コードは以下です。

https://github.com/okaponta/go-practice/blob/master/tour/tour3/exercise-fibonacci-closure/exercise-fibonacci-closure.go

個人的に詰まったポイントです。

 - そもそもクロージャって概念がむずい。
    - 関数型言語触ったことはありつつもなんとなく理解してたのをこれを機に復習。。
 - 初期値を0にするためにフラグを用意した。
    - 問題文が0,1,1,2,3,5,8となってたので、初期値0にしてみました。
 - 2つの変数に一気に代入できることに後から気づいた
    - これをやらないと変数をひとつ増やすことになってました。

## Exercise: Stringers

問題は以下。

https://go-tour-jp.appspot.com/methods/18

コードは以下です。

https://github.com/okaponta/go-practice/blob/master/tour/tour4/exercise-stringer/exercise-stringer.go

個人的に詰まったポイントです。

 - やること自体は直前のページのやつを参考にすればいいので、迷わなかった。
 - 最初は`strings.Join()`を使おうとしたけど、配列の要素が`string`型じゃないので使えず
 - 結局`fmt.Sprintf`で引数をそれぞれ4つ渡す方法で書きました。
    - `%s`じゃなくて`%d`にするところが注意

## Exercise: Errors

問題は以下。

https://go-tour-jp.appspot.com/methods/20

コードは以下です。

https://github.com/okaponta/go-practice/blob/master/tour/tour4/exercise-errors/exercise-errors.go

個人的に詰まったポイントです。

 - `type`の表記。
    - `type`を宣言して、その値を取得する記法でつまずいた
 - 浮動小数点を`printf`したい場合は`%g`、デフォルトの`%v`でもいけるっぽい
 - ゼロ値であるって明確に表記したかったが、わからなかったので`0`を返した

## Exercise: Readers

問題は以下。

https://go-tour-jp.appspot.com/methods/22

コードは以下です。

https://github.com/okaponta/go-practice/blob/master/tour/tour4/exercise-reader/exercise-reader.go

なんだか問題が分かりにくいというかなんというか・・・
実行しながらそれっぽく実装した感じです笑
この後の練習問題をやりながら気づいたのですが、`err`に`io.EOF`を返さない限りは文字列が終わったとみなされないので、無限ストリームになるんですね。きちんと`Read`の説明を読んでなかった、、

## Exercise: rot13Reader

問題は以下。

https://go-tour-jp.appspot.com/methods/23

コードは以下です。

https://github.com/okaponta/go-practice/blob/master/tour/tour4/exercise-rot-reader/exercise-rot-reader.go

個人的に詰まったポイントです。

 - そもそも`main()`内の処理が理解できない。
    - `io.Copy`とか`os.Stdout`とか。
    - 2つめの引数の内容を1つ目の引数に渡す？くらいの理解ですがたぶんよくわかってない。
 - 13個アルファベットをずらすのに、byteは足し算が使える
 - 小文字と大文字があるので、それぞれ処理を書かないといけない。
 - アルファベット以外は処理をしない(処理忘れて最後のビックリを消しちゃったりしました)

## Exercise: Images

問題は以下。

https://go-tour-jp.appspot.com/methods/24

コードは以下です。

https://github.com/okaponta/go-practice/blob/master/tour/tour4/exercise-images/exercise-images.go

個人的に詰まったポイントです。

 - そもそも問題の意味の解読に時間がかかった
    - 最初に実装するものを空実装で書いてみて、前のページの説明をみてたらなんか動いた

以上。まだまだ慣れませんが、なんとなくはわかった気がします笑