func main() { c := 0 for i := 0; i < 1000; i++ { go func() { c++ }() } time.Sleep(time.Second) fmt.Println(c) } • 出力されるcは?先に予想しよう ◦ train-goroutine/mutex/raceに移動 ◦ go run main.go ◦ 出力された結果をチャットにコメント
writing to a map, no other goroutine should be reading or writing the map concurrently. If the runtime detects this condition, it prints a diagnosis and crashes the program
* time.Second) log.Printf("after leak:%d\n", runtime.NumGoroutine()) } func leak(c <-chan string) { // closeされない!! go func() { for cc := range c { log.Println(cc) } }() log.Printf("in leak:%d\n", runtime.NumGoroutine()) } before leak: 1 in leak: 2 after leak: 2
◦ 第一引数で渡す Use context Values only for request-scoped data that transits processes and APIs, not for passing optional parameters to functions. context contextのアンチパターン
log.Printf("failed to open a db err = %s", err.Error()) return } if err := db.PingContext(context.Background()); err != nil { log.Printf("failed to ping err = %s", err.Error()) return } database/sqlに触れてみる
:= make([]string, len(args)) for i, arg := range args { result[i] = arg.String() } return result } type Stringer interface { String() string } GoのGenericsの原則