Goの初心者が最初にはまりそうというか気になりそうなポイント

こんばんわ、ameshoです。

この記事は、Go4 Advent Calendar 2017の18日目です。

私は2017/3/17日から毎週水曜日にプログラミング言語Goの読書会をLancersを会場にして開いています。冒頭から全員で範囲を決めて読み進めていく方式です。途中業務が忙しくて若干出来ない時期がありましたが幸いに再開でき、現在、9章まで来ています。

参加しているのは、ほとんどGo触ったことが無い人も割といまして、私自身も真面目に使うのは今年は行ってからぐらいなので、勉強会で出た内容と、みんなこんなところを気にしたり、はまったりするんだなと言うのをまとめてみました。

Unicodeで文字とされている物がすべて名前として有効

プログラム始めたばかりだと気づかない人多いんですが、最近の言語はUnicodeで文字とされているものが名前として有効だったりします。Goもそれに漏れず対応していまして、

package main

import "fmt"

func main() {
    変数だよ := "hello"
    fmt.Println(変数だよ)
}

このような書き方が出来ます。

追記:

https://twitter.com/mattn_jp/status/942531041503322112

mattnさんにtwitter上でこのようなコメントをいただきましたので。追記致します。実際は全角数字から始まる識別名などは使えません。 @mattnさんありがとうございました。

省略変数宣言

変数宣言が以下のように通常のものと省略変数宣言もありまして、


## 通常
var name type = expression

## 省略
name := expression

これ、どっち使えばいいんですかね?という質問が出たりしました。個人的には、事前にまとめて宣言すると不要なメモリ領域を確保して使わないケースがあるので省略宣言の方がいいのかなと思っていたりします。

変数の生存期間

関数内部で割り当てられたローカル変数を返すことが出来ます。最近のLL使ってる人だとあまりピント来ないかもしれませんが、Cは明示的にヒープかスタックに乗せるか書いてる人が選択出来るので、Cを使ってる方からこういう話が出ました。GCの上で動いているので、変数が到達不能(unreachable)になるまで生存し続けます。

パッケージ変数の初期化は依存関係が解決されてからされる

これも普段スクリプト系を書いている人からすると、便利だなと言う機能で宣言されているパッケージ変数の初期化を考えなくていいという話です。この辺の依存関係を自動で解決してから初期化が始まるので保守とかすごく楽になります。

Goの型の宣言がこの順番の理由

CとかJavaとかを使って人からすると、Goの型宣言がなんでこの順番になっているか疑問に思う人が多いです。私もそうでした。これは、パースに関連していたようで、こちら「Go's Declaration Syntax」に書かれていました。

構造体の宣言はフィールドをまとめて宣言したり、位置を買えたりしただけで違う型として認識される

スクリプト言語を使っていると、Hashとかでデータを使い回したりするんですが、この場合順序を意識したりする必要性はないですが、Goの場合は構造体の宣言の仕方を変えただけで違う型として認識されます。

関数のスタックが可変長

これは、再帰呼び出しの時に関係ある内容で、固定長の場合割と少なめのサイズが設定されていて、再帰呼び出しが深くなるとstackoverflowを起こします。Goの場合は関数のスタックが可変長なので再帰呼び出しの深さをあまり気にせずに再帰を書くことが出来ます。

まとめ

こんな感じで、プログラミング言語Goを読むと意外な落とし穴とか、そんなのあったんだというものに気づかされたりするので読んでみてはいかがでしょうか。