A Tour of Go のまとめ - Basic編 -

個人的に馴染みがないなと思ったところをまとめていく。

Named return values
戻り値となる変数に名前を付けることができる。
戻り値の変数に名前を付けると、 return
式に何も書かずに戻すことができる(nakded return)。
読みやすさの観点から、短い関数でのみ利用すべき。
func split(sum int) (x, t int) {
x = sum * 4 / 9
y = sum - x
return
}

Basic types
Goの基本型
- bool
- string
- int int8 int16 int32 int64
- uint uint8 uint16 uint32 uint64 uintptr
- byte (uint8の別名)
- rune (int32の別名) Unicodeのコードポイントを指す
- float32 float64
- complex64 complex128

Constants
const
キーワードを使って定数を宣言できる。
定数は文字、文字列、boolean、数値のみで使える。
定数は :=
を使って宣言できない。
const Pi = 3.14

If with a short statement
ifは条件の前に、評価するための簡単なステートメントを書くことができる。
ここで宣言された変数はifのスコープ内のみで有効。
func pow(x, n, lim float64) float64 {
if v := math.Pow(x, n); v < lim {
return v
}
}

Switch
GoのSwitchは選択されたcaseのみを実行して、それに続くcaseは実行されない。break文を書く必要もない。
条件のないswitchは switch true
と書くことと同義。
func main() {
os:= runtime.GOOS
switch {
case os == "darwin":
fmt.Println("OS X.")
case os == "linux":
fmt.Println("Linux.")
default:
fmt.Printf("%s.\n", os)
}
}

Defer / Stacking defers
deferは、deferに渡した関数の実行を、呼び出し元の関数の終わりまで遅延させる。
deferへ渡した関数の引数はすぐに評価される。
deferへ渡した関数が複数ある場合は、return時にLIFOの順番で実行される。
func main() {
for i := 0; i < 10; i++ {
defer fmt.Println(i)
}
fmt.Println("done")
}
// done
// 9
// 8
// 7 ...

Pointers
T型のポインタは *T型で、ゼロ値はnilになる。
&
オペレータはそのオペランドへのポインタを引き出す。
*
オペレータはポインタの指す先の変数を示す。
func main() {
i := 42
p := &i
fmt.Println(*p) // 42
*p = 21
fmt.Println(*p) // 21
}

Structs
struct
構造体はフィールドの集まり。
type Vertex struct {
X int
Y int
}

Arrays
[n]T
型は型Tのn個の変数の配列を表す。
長さは型の一部である。よって配列のサイズは固定になる。
var a [10]int

Slices / Slices are like references to arrays
[]T
型は型Tのスライスを表す。
スライスは配列への参照のようなもの。元の配列の部分列を指し示している。
func main() {
names := [4]string{"John", "Paul", "George", "Ringo",}
a := names[0:2]
fmt.Println(a) // [John Paul]
}

Slice length and capacity
スライスは長さと容量の両方を持つ。
スライスの長さ=含まれる要素の数。
スライスの容量=スライスの最初の要素から数えて、元となる配列の要素数。
func main() {
s := []int{2, 3, 5, 7, 11, 13}
a := s[:3]
fmt.Println(len(a)) // 3
fmt.Println(cap(a)) // 6
}

Creating a slice with make
スライスは組み込みの make
関数を利用して作成することもできる。
make関数はゼロ化された配列を割り当て、その配列を指すスライスを返す。
make関数の第3引数にはスライスの容量を指定することができる。
func main() {
a := make([]int, 5)
fmt.Println(a) // [0 0 0 0 0]
}

Range / Range continued
forループに利用する range
は反復ごとに2つの変数を返す。
一つ目はインデックスで、2つ目はインデックスの場所の要素のコピー。
それぞれ _ に代入することで捨てることができる。
func main() {
for i, v := range array {
fmt.Println(i, v)
}
}

Maps
mapはキーと値とを関連付ける。
make関数は指定された型のマップを初期化する。
func main() {
var m map[string]Vertex
m = make(map[string]Vertex)
}

Function closures
Goの関数はクロージャの特性を持つ。外部のスコープの変数を参照し続ける。
以下のadder()関数からreturnされる関数は、スコープ外のsum変数を参照し続ける。
func adder() func(int) int {
sum := 0
return func(x int) int {
sum += x
return sum
}
}
func main() {
pos, neg := adder(), adder()
fmt.Println(pos(1)) // 1
fmt.Println(pos(2)) // 3
fmt.Println(pos(3)) // 6
fmt.Println(neg(-1)) // -1
fmt.Println(neg(-2)) // -3
fmt.Println(neg(-3)) // -6
}