【Go】いろいろめも

Go言語のメモ帳です。
随時更新していきます。
※ほんとに初心者の書き込みです。

次回

>https://go-tour-jp.appspot.com/methods/1


# A Tour of Go

>http://go-tour-jp.appspot.com/

# 計算

```
1e9  /* 1000000000 */
2**n /* ２のn乗 */
1<<n /* 1(int)を左にシフト */
```

# ポインタ

```
/* 構造体へのポインタ参照 */
s = := T{}
t := &s

/* 直接ポインタ参照 */
t := &T{}

/* newでも同等 */
var t *T = new(T)
t := new(T)

/* intにintのポインタは代入できない cannot use &a (type *int) as type int in assignment */
var i int
a := 1
i = &a
```

newがポインタ・・・java出身の自分としてはなかなか強烈。Cだと当然？
あと構造体ってオブジェクトって言ったらあかんのかな。


# struct

javaでいうクラス？みたいなもの？
struct名{}でアクセスする感じ。
{}内でフィールドを初期化できるが、:フィールド名でフィールド指定の初期化が可能。

指定がない場合は

- フィールド数分引数を指定する（宣言順？）
- 指定なし（各フィールドの初期値）



```
package main

import "fmt"

type Vertex struct {
    X, Y int
}

var (
    p = Vertex{1, 2}  // has type Vertex
    q = &Vertex{1, 2} // has type *Vertex
    r = Vertex{Y: 1}  // Y:0 is implicit
    s = Vertex{}      // X:0 and Y:0
)

func main() {
    fmt.Println(p, q, r, s)
}
```

# 出力

>fmt.Printf("%d", 1)

一番最初がフォーマットで、後の引数がフォーマットの%dに置き換えられる？


>fmt.Println("", 1)

引数順に連結されて出力される

# for文

```
for i ; i < 10 ; i++ {}
```
```
for i < 10 ; i++ {}
```
```
var pow = []int{1, 2, 4, 8, 16, 32, 64, 128}
for i, v := range pow {fmt.Printf("2**%d = %d\n", i, v)}
```

Goは繰り返しはfor文のみ。

# slice
```
var s = []int{1, 2, 3} # len=3 cap=3 [1 2 3]
```
```
var s = make([]int, 5) # len=5 cap=5 [0 0 0 0 0]
```
```
var s = make([]int, 0, 5) # len=0 cap=5 []
```

**注意点**
sliceを再sliceした場合はあくまで参照渡しなので、再sliceした内容を変更するとslice元も変更される。

```slice.go
p := []int{2, 3, 5, 7, 11, 13}

/* p == [2 3 5 7 11 13] */
fmt.Println("p ==", p)

q := p[1:4]

/* q == [3 5 7] */
fmt.Println("q ==", q)

q[1] = 3

/* q == [3 3 7] */
fmt.Println("q ==", q)

/* p == [2 3 3 7 11 13] */
fmt.Println("p ==", p)
```

Goで「参照渡し」という表現は正しいのだろうか・・・


# Map

jsonみたいに書ける

```
map := map[string]int {
  "1": 1,
  "2": 2,
}
```

structも

```
map := map[string]St {
  "st1": St{ 1, 2, },
  "st2": St{ 1, 3, },
}
```

makeでも

```
map := make(map[string]int)
```

json形式の場合って、最後もカンマ入れないとエラーになるんですね・・・

>map := map[string]int {
>  "1": 1,
>  "2": 2, <- ここ！
>}

>map := map[string]St {
>  "st1": St{ 1, 2, <-こことか！ },
>  "st2": St{ 1, 3, },<-こことか！
>}

Javaだと終わりにカンマ付けない風習だから結構なれるまで時間がかかりそう・・・

# switch

Goのswitchは、case後に自動でbreakする。
breakさせないためには「fallthrough」を記述すればOK。

条件に演算を用いることも可能。

```
switch n := 1; n {
case 0:
    fmt.Println("0")
case 1:
    fmt.Println("1")
    fallthrough               /* breakさせない */
case n + 1 == 3               /* 演算で条件判定 */
    fmt.Println("2")
default:
    fmt.Println("default!")
}
```

# Defer

A Tour of Goのまんま。
これは何が便利なのだろう、使っていかないとわからない。。。
引数だけ先に評価されて、実行が遅延するのがよいのか？

```
func main() {
    defer fmt.Println("Go!")
    defer fmt.Println("of")
    defer fmt.Println("world")
    fmt.Println("hello")
    /* hello world of Go! */
}
```

しかも後にスタックしたものが先にポイされる。気をつけないと。

#Methods

structを引数（メソッドレシーバ）に指定するとあたかもそのstructで宣言されているメソッドのように呼び出すことが出来る。
javascriptの様に後からfunctionを追加するイメージであってますかね。

```
type Vertex struct {
	X, Y float64
}

func (v *Vertex) Abs() float64 {
	return math.Sqrt(v.X*v.X + v.Y*v.Y)
}

func main() {
	v := &Vertex{3, 4}
	fmt.Println(v.Abs())
}
```

# その他

```
math.Sqrt(25) /* 平方根 5*/
```

2015/12/01　なんか A Tour of Go の章立てとか変更されてる！ 

# 演習問題

**Map**

```
package main

import (
    "code.google.com/p/go-tour/wc"
    "strings"
)

func WordCount(s string) map[string]int {
	ret := make(map[string]int)
	for _,v := range strings.Fields(s) {
		ret[v] = ret[v] + 1
	} 
	return ret
}

func main() {
    wc.Test(WordCount)
}
```

**closure**

```
package main

import "fmt"

// fibonacci is a function that returns
// a function that returns an int.
func fibonacci() func() int {
	a, b := 0, 1
	return func() int {
		a, b = b, a + b
		return b
	}
}

func main() {
	f := fibonacci()
	for i := 0; i < 10; i++ {
		fmt.Println(f())
	}
}
```