プログラム構造(プログラミング言語Go)
名前
関数の外で宣言した名前はファイルが違っても同一パッケージであれば見える
予約語と事前宣言は違う:事前宣言された名前は再定義できる
宣言: var, const, type, func
変数
var name type = expression typeと = expressionのどちらかは省略できる
typeが省略されると右辺の初期化式で型が決まる
初期化式が省略されると、その型に対するゼロ値(zero value)が初期値となる。
参照型とインタフェースのゼロ値はnil
Goの参照型とはpointer, slice, map, channel, function
省略変数宣言 short variable declaration
i, j := 0, 1 とも書ける
少なくとも1つの新たな変数を宣言していれば使える
タプル代入 tuple assignment i, j = j, i
ポインタ
変数(variable) = 値を含んでいる記憶域
pointerの値は変数のアドレス(address)です。
全ての値がアドレスを持つわけではないが、全ての変数はアドレスを持つ(重要そう)
pointer pが指している変数は*pと書かれる
変数は、アドレス化可能な値(addressable value)とも言われる
変数を表すのはaddress-of演算子&が適用できる式だけ
pointerのゼロ値は常にnil
pointerは比較可能
関数がローカル変数のアドレスを返すことができる
ポインタは変数のアドレスを持っているので、関数にポインタ引数を渡すことで、関数が変数を更新できる
new関数(組み込み関数)
式new(T)はT型の無名変数 (unnamed variable)を作成し、Tのゼロ値に初期化し、*T型の値であるそのアドレスを返す。
構文上便利というだけで、fundamentalな存在ではない(他の方法でも実現できる)
newはあまり使われない:よく使われる無名変数は構造体型であって、構造体型には構造体リテラル構文がある
変数の生存期間(lifetime)
とは、プログラムを実行する際にその変数が存在する期間です。
パッケージレベル変数の場合→プログラムの実行全体
ローカル変数は動的な生存期間を持つ
宣言文が実行されるごとに生成され、到達不可能(unreachable)になるまで生存する。
関数のパラメータと結果もローカル変数である
ガベージコレクタ
代入
タプル代入
code:gcd.go
func gcd(x, y int) int {
for y != 0 {
x, y = y, x%y
}
return x
}
関数の戻り値の2つ目がerrorやboolを返すのがよくある
マップの検索(4.3), 型アサーション(7.10), チャネル受信(8.4.2)がok boolを返す
代入可能性
左辺(変数)の型に右辺の値が代入可能(assignable)であれば代入は正当である
2つの値を==!=で比較できるかどうかは代入可能性と関連する=どちらかがどちらかに代入可能
新たな型が出てくるたびに代入可能性と比較可能性comparabilityを説明する
型宣言
type宣言は、既存の型と同じ基底型 underlying type を持つ新たな名前付き型 named typeを定義します。
type name underlying-type
全ての型Tに対して、値xをT型へ変換するような対応する変換演算T(x)が存在する。
変換演算は関数呼び出しではない -> 要検証
1つの型から別の型への変換は、次の場合に許される。
両方の型が同じ基底型を持つ場合
両方の型が同じ基底型の変数を指す無名のポインタ型の場合
xがTへ代入可能であれば、変換は許されるがたいていは冗長となる
パッケージとファイル
スコープ