part1の続き
makeとnewの違い
どちらも値を入れずメモリ領域を確保する。違いはポインタが返ってくるかどうか。
// 返ってこない
s := make([]int, 0)
m := make(map[string]int)
ch := make(chan int)
// 返ってくる
var p *int = new(int)
var st = new(struct{})
cf. 中身はnil (メモリ確保していない)
var s []int
var m map[string]int
var ch chan int
var p *int 
struct
type Vertex struct {
	X, Y int
	S string
}
v1とv2は同じ意味。v3とv4は同じ意味。
v1 := Vertex{} // {0 0  }
var v2 Vertex // {0 0  }
v3 := new(Vertex) // &{0 0  }
v4 := &Vertex{} // &{0 0  }
	changeVertex := func(v Vertex) {
		v.X = 1000
	}
	changeVertex2 := func(v *Vertex) {
		v.X = 1000 // (*v).X = 1000 と同じ意味になる
	}
	v := Vertex{1, 2, "test"}
	changeVertex(v) // 値渡し
	fmt.Println(v) // {1 2 test} 値が書き換わっていない
	changeVertex2(&v) // 参照渡し
	fmt.Println(v) // {1000 2 test} 値が書き換わっている
structオリエンテッド
package main
import "fmt"
type Vertex struct {
	x, y int // 先頭が小文字だとpackage内からのみ参照可能
}
// メソッド(値レシーバー)
func (v Vertex) Area() int {
	return v.x * v.y
}
// メソッド(ポインタレシーバー) 中身を書き換える!
func (v *Vertex) Scale(i int) {
	v.x = v.x * i
	v.y = v.y * i
}
// Embedded(継承みたいなやつ)
type Vertex3D struct {
	Vertex
	z int
}
func (v Vertex3D) Area3D() int {
	return v.x * v.y * v.z
}
func (v *Vertex3D) Scale3D(i int) {
	v.x *= i
	v.y *= i
	v.z *= i
}
// コンストラクタ
func New(x, y, z int) *Vertex3D {
	return &Vertex3D{Vertex{x, y}, z}
}
func main() {
	v := New(4, 5, 6)
	v.Scale3D(10)
	fmt.Println(v.Area()) // 継承元のメソッドも使える
	fmt.Println(v.Area3D())
}
non-struct
自分なりの型とメソッドを作れる。
type MyInt int
func (i MyInt) Double() int {
	return int(i * 2)
}
インターフェースとダックタイピング
package main
import "fmt"
// 設計書みたいなイメージ
type Human interface {
	Say() string // 実装しないといけない関数を書く
}
type Person struct {
	Name string
}
func (p Person) Say() string {
	return "Mr." + p.Name
}
// インターフェースのダックタイピング(Say()というメソッドがないと成立しないときに使う)
func DriveCar(human Human) {
	if human.Say() == "Mr.Mike" {
		fmt.Println("Run")
	} else {
		fmt.Println("Get out")
	}
}
func main() {
	var mike Human = Person{"Mike"} // Humanにstructを入れたら、Say()というメソッドがないとだめ
	DriveCar(mike)
}
タイプアサーションとswitch type文
// 引数が interface{} →何でも引数として受け入れる!
func do(i interface{})  {
	/* タイプアサーション: interfaceを他の型に変える
	ii := i.(int)
	ss := i.(string) など
	*/
	// switch type 文
	switch v := i.(type) {
	case int:
		fmt.Println(v * 2)
	case string:
		fmt.Println(v + "!!!!")
	default:
		fmt.Printf("I don't know %T.\n", v)
	}
}
Stringer
package main
import "fmt"
type Person struct {
	Name string
	Age int
}
// String()のメソッドを実装すれば fmt の出力を変えることができる!
func (p Person) String() string {
	return fmt.Sprintf("My name is %v, I'm %v years old.", p.Name, p.Age)
}
func main() {
	mike := Person{"Mike", 20}
	fmt.Println(mike) // My name is Mike, I'm 20 years old.
}
カスタムエラー
package main
import "fmt"
// 自分なりのエラーを作る
type UserNotFound struct {
	Username string
}
// 作ったエラーにError()のメソッドを実装するとエラー時にこれが出力される
func (e *UserNotFound) Error() string {
	return fmt.Sprintf("User not found: %v", e.Username)
}
func myFunc() error {
	// something wrong
	ok := false
	if ok {
		return nil
	}
	return &UserNotFound{Username: "mike"}
}
func main() {
	if err := myFunc(); err != nil{
		fmt.Println(err) // User not found: mike
	}
}
Error()をポインタレシーバーにする理由:エラーが違う場所で起きたときに比較判定するため。
以下サンプルコード。err == io.EOFの部分。
err == errors.New("EOF")としてもうまく行かない。→ r.Read()が io.EOFというエラーを返すため。
package main
import (
	"fmt"
	"io"
	"strings"
)
func main() {
	r := strings.NewReader("Hello, Reader!")
	b := make([]byte, 8)
	for {
		n, err := r.Read(b)
		fmt.Printf("n=%v err=%v b=%v\n", n, err, b)
		fmt.Printf("b[:n]=%q\n", b[:n])
		if err == io.EOF{
			break
		}
	}
}