Go言語に触れてみよう Part.2

# はじめに
前回からだいぶ時間が経ってしまいました。。。

今回は、Tour of Goに触れていきながらGoの文法・構文についてみていきます。

# Tour of Go

以下からサイトに飛んでください。
[Tour of Go](https://go-tour-jp.appspot.com/welcome/1)

Tour of Goの日本語訳なのでかなり読みやすくわかりやすいです。
また、Go言語を学ぶためにはかなりいい教材だと思っています。

では、演習をみていきましょう！！
（全ての演習をやっていきません。ごめんなさい。。。）

## Package・Import
演習前に基本的な文法をおさらいします。

基本的にpackageについては`main`。

ただ、ディレクトリ管理によってはpackege名を変える必要があるため、
Go言語のWebアプリ開発で注意。

importはGo言語ではグループ化があります。

```go
import (
    "string"
    . "fmt"
    m "math"   
)
```

"fmt"と"math"の書き方は、それぞれ**ドット操作**、**エイリアス操作**といいます。
こうすることで、fmtパッケージやmathメソッドを呼び出す際に省略・簡略可能になります。

```go
fmt.Println("hoge")

Println("hoge") // 省略

math.Abs(-12.34)

m.Abs(-12.34) // 簡略
```

## Exercise: Loops and Functions

色々進めていくと、関数や変数宣言、for・while・if文が紹介されます。

初めの演習問題は、平方根の計算をmathメソッドを使わずに実装するものです。
ヒントとして、`z -= (z*z - x) / (2*z)`と`z := 1.0 or z := float64(1)`
を使用したらできるそうです。

また、指定として10回ループしてから、結果を出します。

```go:exercise-loops-and-functions.go
package main

import (
	"fmt"
)

func Sqrt(x float64) float64 {
	// z := 1.0
	z := float64(1)
	
	for i := 0; i < 10; i++ {
		z -= (z*z - x) / (2*z)
    }
    return z
}

func main() {
	fmt.Println(Sqrt(2))
}
```

## Exercise: Slices
演習を終えると、switch文やdefer、pointer、Array・Sliceなどの説明があります。ここから初心者の方は難しくなっていきます。

pointerに関しては、C言語での勉強をお勧めします。

ここでの演習は、Sliceでの2次元配列を使用して画像を表示するものです。

```go:exercise-slices.go
package main

import "golang.org/x/tour/pic"

func Pic(dx, dy int) [][]uint8 {
	pic := make([][]uint8, dy)
	for y := range pic {
        pic[y] = make([]uint8, dx)
        for x := range pic[y] {
            pic[y][x] = uint8((x + y) / 2)
			// pic[y][x] = uint8(x * y)
			// pic[y][x] = uint8(x ^ y)
        }
    }
    return pic
}

func main() {
	pic.Show(Pic)
}
```

## Exercise: Maps
続いては、mapです。
扱いについては、ArrayやSliceと似ている部分があるため、
そんなに難しくはありません。

演習では、mapを使用してテストケースをしっかりと走らせるものです。
ここで、`strings`のメソッドを使用して引数に渡った文字列を分解していきます。

```go:exercise-maps.go
package main

import (
	"strings"

	"golang.org/x/tour/wc"
)

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

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

## Exercise: Fibonacci closure
関数のクロージャーについて学びます。

演習は、Fibonacci数列を実装します。
Fibonacci数列は、「2つ前の項と1つ前の項を足し合わせていくことでできる数列」のことです。
`1, 1, 2, 3, 5, 8, 13, 21 ...`

これをクロージャーでやっていきます。

```go:exercise-fibonacci-closure.go
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 a
    }
}

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

## Exercise: Stringers
ここからは関数とメソッドの違いやpointerとの関係、interfaceなどを学んでいきます。少し難しくなっていきます。

演習では、interfaceの一つであるfmt内の`Stringer`を使用して、
IPアドレスを出力します。

```go:exercise-stringers.go
package main

import "fmt"

type IPAddr [4]byte

// TODO: Add a "String() string" method to IPAddr.
func (addr IPAddr) String() (s string) {
    for _, v := range addr {
        s += fmt.Sprintf("%d.", v)
    }
    return s[:len(s)-1]
}

func main() {
    hosts := map[string]IPAddr{
        "loopback":  {127, 0, 0, 1},
        "googleDNS": {8, 8, 8, 8},
    }
    for name, ip := range hosts {
        fmt.Printf("%v: %v\n", name, ip)
    }
}
```

## Exercise: Errors
ここでは、Go言語におけるエラーハンドリングを学びます。

```go:exercise-errors.go
package main

import (
    "fmt"

)

type ErrNegativeSqrt float64

func (e ErrNegativeSqrt) Error() string {
    return fmt.Sprintf("cannot Sqrt negative number: %f", float64(e))
}

func Sqrt(x float64) (float64, error) {
	if x < 0 {
        return 0, ErrNegativeSqrt(x)
    }
	// z := 1.0
	z := float64(1)
	
	for i := 0; i < 10; i++ {
		z -= (z*z - x) / (2*z)
    }
    return z, nil
}

func main() {
    fmt.Println(Sqrt(2))
    fmt.Println(Sqrt(-2))
}
```

## Exercise: Readers
ioパッケージのReaderinterfaceを使ってioデータを読み取ります。

```go:exercise-readers.go
package main

import "golang.org/x/tour/reader"

type MyReader struct{}

// TODO: Add a Read([]byte) (int, error) method to MyReader.
func (a MyReader) Read(rb []byte) (n int, e error) {
    for i, _ := range rb {
        rb[i] = 'A'
        n++
    }
    return
}

func main() {
    reader.Validate(MyReader{})
}
```

## Exercise: rot13Reader
前の演習と同じような感じでReaderinterfaceを使用します。

```go:exercise-rot13reader.go
package main

import (
    "io"
    "os"
    "strings"
)

type rot13Reader struct {
    r io.Reader
}

func (a *rot13Reader) Read(rb []byte) (n int, e error) {
    n, e = a.r.Read(rb)
    if e == nil {
        for i, v := range rb {
            switch {
            case v >= 'A' && v <= 'Z':
                rb[i] = (v-'A'+13)%26 + 'A'
            case v >= 'a' && v <= 'z':
                rb[i] = (v-'a'+13)%26 + 'a'
            }
        }
    }

    return
}

func main() {
    s := strings.NewReader("Lbh penpxrq gur pbqr!")
    r := rot13Reader{s}
    io.Copy(os.Stdout, &r)

    s2 := strings.NewReader("You cracked the code!")
    r2 := rot13Reader{s2}
    io.Copy(os.Stdout, &r2)
}
```

## Exercise: Images
今までの3つでinterfaceの使い方を学ぶものなので、readerと同じように書きます。

```go:exercise-images.go
package main

import (
    "golang.org/x/tour/pic"
    "image"
    "image/color"
)

type Image struct{}

func (im Image) ColorModel() color.Model {
    return color.RGBAModel
}

func (im Image) Bounds() image.Rectangle {
    return image.Rect(0, 0, 255, 255)
}

func (im Image) At(x, y int) color.Color {
    v := uint8(x * y)
    return color.RGBA{v, v, 255, 255}
}

func main() {
    m := Image{}
    pic.ShowImage(m)
}
```

# 終わり
これでとりあえずの基本的なことができるようになると思います。
もっと深くやりたい人は、次の章に進んでください。