速習a tour of go

27
速習 A tour of Go 金谷 敦志 (@todogzm) 13917日火曜日

Upload: -

Post on 27-Jun-2015

714 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: 速習A tour of go

速習 A tour of Go金谷 敦志 (@todogzm)

13年9月17日火曜日

Page 2: 速習A tour of go

本資料について

A tour of Goからハンズオンに必要な分を抽出

ハンズオンに必要な未記載分を追記

A tour of Goまたは言語仕様の復習をお勧め

13年9月17日火曜日

Page 3: 速習A tour of go

ハンズオンにあたって自身のPCへのGoインストールを推奨しますGo Playgroundでは一部機能に制限あり

Goファイルは、ハンズオンの課題ごとにフォルダを作成して、そこに置いてください。

ソースのビルドは go build

ソースのテストは go test

13年9月17日火曜日

Page 4: 速習A tour of go

//フォルダ単位でパッケージ名を付けるpackage main

//インポートするパッケージ名import ( "fmt")

//mainパッケージにmain()を置けば実行形式が作られるfunc main() { // パッケージ名.関数名 fmt.Println("Hello, world.") }

基本構文

13年9月17日火曜日

Page 5: 速習A tour of go

// intの引数x, yを取ってintの結果を返すfunc add(x int, y int) int { return x + y}

//複数の値を返すことができる → Cの参照渡しのようなことが不要func swap(x, y string) (string, string) { //x,yが同じ型→省略可 return y, x}

//関数をデータとして持つことができるfn := function(a, b int) int { return a * b}

//クロージャも使えるfunc adder() func(int) int { sum := 0 return func(x int) int { sum += x return sum }}

関数

13年9月17日火曜日

Page 6: 速習A tour of go

//型は 後。x,y,zはint型var x, y, z int

//初期化子(initializer)指定時は型指定不要var c, python, java = true, 3, "no"

// 関数内では:=を使うことでvar指定が不要c, python, java := true, 3, "no"

変数

13年9月17日火曜日

Page 7: 速習A tour of go

bool

string

int int8 int16 int32 int64uint uint8 uint16 uint32 uint64uintptr //ポインタの値をそのまま格納するのに充分な大きさの符号なし整数

byte // uint8 の別名

rune // int32 の別名 // Unicode のコードポイントを表す

float32 float64

complex64 complex128

基本型

13年9月17日火曜日

Page 8: 速習A tour of go

// 型は指定しないconst Pi = 3.14

const (A = 1B = "test"

)

定数

13年9月17日火曜日

Page 9: 速習A tour of go

package main

import "fmt"

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

for文

13年9月17日火曜日

Page 10: 速習A tour of go

// while文は下記のように書くfor sum < 55 {}

// 無限ループfor {}

whileもforで書く

13年9月17日火曜日

Page 11: 速習A tour of go

package main

import ( "fmt" "math")

func sqrt(x float64) string { if x < 0 { return sqrt(-x) + "i" } return fmt.Sprint(math.Sqrt(x))}

func main() { fmt.Println(sqrt(2), sqrt(-4))}

if文

if a := 3; a < 5 { // if文内にif文スコープ内で有効な変数を宣言}fmt.Println(a) //スコープ外のためエラー

13年9月17日火曜日

Page 12: 速習A tour of go

switch i {case 0: fmt.Println("Zero")case 1: fmt.Println("One")case 2: fmt.Println("Two")case 3: fmt.Println("Three")case i>3: fmt.Println("More") // 評価式も書けるdefault: fmt.Println("Unknown")}

switch文

13年9月17日火曜日

Page 13: 速習A tour of go

package main

import "fmt"

type Vertex struct { //publicな型Vertex X int //publicなフィールド変数X, Y Y int}

func main() { v := Vertex{1, 2} //v.X = 1; v.Y = 2で初期化 v.X = 4 //フィールドへのアクセスは.を使う fmt.Println(v.X)}

struct

13年9月17日火曜日

Page 14: 速習A tour of go

type Vertex struct { X int Y int}func main() { p := Vertex{1, 2} q := &p //pへのポインタを渡す q.X = 1e9 //qはpへのポインタなので、p.Xが書き換わる fmt.Println(p)}

pointer

var ( p = Vertex{1, 2} // has type Vertex q = &Vertex{1, 2} // has type *Vertex r = Vertex{X: 1} // Y:0 is implicit s = Vertex{} // X:0 and Y:0)var q *Vertex = new(Vertex) //ポインタ変数を作成

13年9月17日火曜日

Page 15: 速習A tour of go

// sliceは、値の配列を参照// 長さ( length )も含む// 配列もあるがsliceで代替できるため割愛

func main() { p := []int{2, 3, 5, 7, 11, 13} //intのslice fmt.Println("p ==", p)

for i := 0; i < len(p); i++ { fmt.Printf("p[%d] == %d\n", i, p[i]) }}

slice

13年9月17日火曜日

Page 16: 速習A tour of go

slicing → p[0:3]など

容量指定a := make([]int, 5) //len(a) = 5, cap(a) = 5a := make([]int, 0, 5) //len(a) = 0, cap(a) = 5

sliceの各要素の処理for i, v := range p { //iはインデックス、vは値}

不要な変数 → _ を使うfor _, v := range p {}

appendb := append(a, 8) //aと同じ型で、要素に8を追加したsliceを返す

sliceに対する操作

13年9月17日火曜日

Page 17: 速習A tour of go

// map はキーと値とを関連付ける// mapの初期化にはmakeを使う

type Vertex struct { Lat, Long float64}

var m map[string]Vertex

func main() { //キーがstring, 値がVertexのmapを作成 m = make(map[string]Vertex) m["Bell Labs"] = Vertex{ 40.68433, -74.39967, } fmt.Println(m["Bell Labs"])}

map

13年9月17日火曜日

Page 18: 速習A tour of go

m := make(map[string]int)

m["Answer"] = 42fmt.Println("The value:", m["Answer"]) // 42が出力

m["Answer"] = 48fmt.Println("The value:", m["Answer"]) // 48が出力

delete(m, "Answer")fmt.Println("The value:", m["Answer"]) // 0(intの初期値)

v, ok := m["Answer"] //キーの有無チェックをok(bool)で判定fmt.Println("The value:", v, "Present?", ok)

for k, v := range m { //キーと値のペアでループを回す fmt.Println(“Key:”, k, “, Value:”, v)}

mapに対する操作

13年9月17日火曜日

Page 19: 速習A tour of go

type Vertex struct { X, Y float64}

// Vertex型のポインタ型にAbsメソッドを定義func (v *Vertex) Abs() float64 { //mathのインポートが必要 return math.Sqrt(v.X*v.X + v.Y*v.Y)}

func main() { v := &Vertex{3, 4} fmt.Println(v.Abs()) //struct変数.メソッド名 でメソッド呼び出し}

// 同一パッケージ上の型(基本型以外)にメソッドを定義できる

// ポインタ型にすることで、各メソッド呼び出し時の値コピーを防ぐ// また、ポインタ型だとstructの値更新ができる

Methods

13年9月17日火曜日

Page 20: 速習A tour of go

type Abser interface { Abs() float64}

// 引数なしで返り値の型がfloat64であるAbs()メソッドを// 持つ型はAbserインタフェースが実装済みと判断される// つまりインタフェースを実装する、という宣言が不要

Intefaces

13年9月17日火曜日

Page 21: 速習A tour of go

import ("fmt""strconv"

)

func main() { // エラーの可能性がある関数は複数の値を返す関数となっている

i, err := strconv.Atoi("102")if err != nil { //変換失敗時の処理

fmt.Println("Cannot parse : ", err)return

}fmt.Println("Parsed: ", i)

}

Errors

// 多値を受け取りerror型がnilか否かでエラー判定する// errorインタフェースは下記の通り

type error interface { Error() string}

// panic/recoverという仕組みもあるが、致命的なエラーの場合のみに使用される

13年9月17日火曜日

Page 22: 速習A tour of go

go someFunc() // someFuncが別のgoroutineで実行される

//goステートメントは独立したgoroutine(スレッド)として//関数またはメソッドを同一アドレス空間内で行う//返り値は取得できない(破棄される)

goroutine

13年9月17日火曜日

Page 23: 速習A tour of go

// goにより並行処理の実行自体は容易になった// 並行処理した結果をまとめる部分はchannelを使う

// channelはチャネルオペレータの <- を用いて値の送受信ができる直通ルートの型// アクターモデルで言うメールボックス、JavaだとLinkedBlockingQueueなど…// ロックによる排他制御も可能だが普通は使わない

c := make(chan int) // intのチャンネルを作成c <- 3 // 3をchannelに送る。cの受信準備ができるまでブロックv := <-c //cに値が来るまでブロックし、値が来れば受け取る

c := make(chan int, 100) //受信バッファを 大100件とする

goroutine / channel

13年9月17日火曜日

Page 24: 速習A tour of go

// 複数チャンネルからの受信を待つ場合にはselectを使う// switch文と似た文法だが、caseが実行されるのは、// 指定のchannelが送受信できるとき// それまではブロック

select {case c <- x: //channel xから受信出来た場合は下記を計算 x, y = y, x+ycase <-quit: // channel quitから受信できたときは処理終了 fmt.Println("quit") return}

select

13年9月17日火曜日

Page 25: 速習A tour of go

A tour of Goにない話

13年9月17日火曜日

Page 26: 速習A tour of go

// deferの後に続く式を書く// second()はdeferTest()からリターンする直前に実行される

func deferTest() { defer second() first()}

// こういうケースで便利f, _ := os.Open(filename)defer f.Close() //処理終了後に確実に閉じる

defer

13年9月17日火曜日

Page 27: 速習A tour of go

// 同一フォルダ内にファイル名_test.go で置くのが一般的// テスト関数はpublic, 引数には *testing.Tを渡す// テスト実行は go test [ファイル名から.goを除去したもの]// t.Errorまたはt.Fatalが実行されればそのテストは失敗と判断

import ( "testing")

func TestFizzBuzz(t *testing.T) { if result := FizzBuzz(1); result != 1 { t.Error("Expected : 1, Actual : ", result) }

if result := FizzBuzz(3); result != "Fizz" { t.Error("Expected : 3, Actual : ", result) }}

テスト

13年9月17日火曜日