【GO】Golangの勉強を始めたから殴り書きのメモ~その4
つづき。 tour.golang.org
Errors
- goはエラーをエラー値で表現する。
package main import ( "fmt" "time" ) // 構造体 type MyError struct { When time.Time What string } func (e *MyError) Error() string { return fmt.Sprintf("at %v, %s", e.When, e.What) } func run() error { return &MyError{ time.Now(), "it didn't work", } } func main() { // err := run() // if err != nil {...} と同意 if err := run(); err != nil { fmt.Println(err) } }
Readers
package main import ( "fmt" "io" "strings" ) func main() { r := strings.NewReader("Hello, Reader!") // strings.Readerを作成し、8byte毎に読み出しています。 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]) // 末端まで行ったらbreak if err == io.EOF { break } } }
Goroutines
- Goのランタイムに管理される軽量なスレッド
package main import ( "fmt" "time" ) func say(s string) { for i := 0; i < 5; i++ { time.Sleep(100 * time.Millisecond) fmt.Println(s) } } func main() { // これでごルーチンが実行される go say("world") say("hello") }
Channels
package main import "fmt" func sum(s []int, c chan int) { sum := 0 for _, v := range s { sum += v } // sumをcに送る c <- sum } func main() { s := []int{7, 2, 8, -9, 4, 0} // チャネルを生成する c := make(chan int) go sum(s[:len(s)/2], c) go sum(s[len(s)/2:], c) // チャネルcから値を受け取る x, y := <-c, <-c fmt.Println(x, y, x+y) // -5 17 12 }
- Buffered Channels
package main import "fmt" func main() { // バッファの2ついたチャネルを作成 // いっぱい渡すとバッファがつまる ch := make(chan int, 2) ch <- 1 ch <- 2 fmt.Println(<-ch) // 1 fmt.Println(<-ch) // 2 }
- Range and Close
package main import ( "fmt" ) func fibonacci(n int, c chan int) { x, y := 0, 1 for i := 0; i < n; i++ { // チャネル c <- x x, y = y, x+y } // クローズした後に追加するとpanic close(c) } func main() { // 10のバッファ付きチャネルを作成 c := make(chan int, 10) go fibonacci(cap(c), c) for i := range c { fmt.Println(i) } }
- select
package main import "fmt" func fibonacci(c, quit chan int) { x, y := 0, 1 for { select { case c <- x: x, y = y, x+y case <-quit: fmt.Println("quit") return } } } func main() { // チャネルを作成 c := make(chan int) // チャネルを作成Part2 quit := make(chan int) go func() { for i := 0; i < 10; i++ { fmt.Println(<-c) } quit <- 0 }() fibonacci(c, quit) } /** 0 1 1 2 3 5 8 13 21 34 quit */
- Default Selection
package main import ( "fmt" "time" ) func main() { tick := time.Tick(100 * time.Millisecond) boom := time.After(500 * time.Millisecond) for { select { case <-tick: fmt.Println("tick.") case <-boom: fmt.Println("BOOM!") return // 何にも該当しなければdefaultに入る default: fmt.Println(" .") time.Sleep(50 * time.Millisecond) } } }