Go言語(プログラミング)入門メモ㉒

## selectでdefaultとbreakを使用する。
selectでチャネルに応じてそれぞれの処理を作成したが、どのチャネルでもないときの処理はdefaultを使って書くことができる。また、for文とselect文を使う時にラベルを使って途中で処理を抜けることもできる。

## selectとdefaultでどのチャネルでもない処理を書く。
~~~
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:
			fmt.Println("    .")
			time.Sleep(50 * time.Millisecond)
		}
	}
}

//以下のように出力される
    .
    .
tick.
    .
    .
tick.
    .
    .
tick.
    .
    .
tick.
    .
    .
BOOM!
~~~
time.Tickとtime.Afterは、それぞれ設定した時間に値が送信されるチャネルを返す。time.Tickは設定した時間ごとに周期的にチャネルへと値を送信し、time.Afterは設定した時間が経過したタイミングで値を送信する。ここではtime.Tickは100ミリ秒ごとに、time.Afterでは500ミリ秒後に値を送信するチャネルを作成している。
設定した時間でチャネルに送信されたデータは、selectでチャネルごとに処理される。
どちらのcaseでもない場合、defaultで「　.」が表示されたあとに50ミリ秒待機してから次のループに進む。「BOOM!」が表示されたあとは、returnで終了している。

## for文とselect文を途中で抜ける
例えば、for文の中に「fmt.Println("#####")」と書いて実行しても表示結果は変わらない。これは、returnの時点で処理が終了してしまい、「fmt.Println("#####")」は実行されていないため。
~~~
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:
			fmt.Println("    .")
			time.Sleep(50 * time.Millisecond)
		}
	}
    fmt.Println("#####")
}

//以下のように出力される
    .
    .
tick.
    .
    .
tick.
    .
    .
tick.
    .
    .
tick.
    .
    .
BOOM!   ←処理結果変わらず。
~~~

returnの代わりにbreakを書いた場合は、for文から抜け出せず無限ループになってしまう。
~~~
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!")
            break    //returnの代わりにbreakを書く
			//return
		default:
			fmt.Println("    .")
			time.Sleep(50 * time.Millisecond)
		}
	}
}

//以下のように出力される
    .
    .
tick.
    .
    .
tick.
    .
    .
tick.
    .
    .
tick.
    .
    .
BOOM!　　←「BOOM!」が表示されたあともfor文の処理が終了しない
tick.
    .
    .
tick.
    .
    .
以下略
~~~
breakは、最も内側のfor文、select文、switch文を抜ける。このため、select文からは抜けられたが、その外側のfor文から抜けられる、無限ループになってしまっている。

## ラベルを使用してforループを抜ける
Goではラベルを使用することでループを抜けることができる。
for文の上に「OutLoop:」と書いて、for文にOutLoopという名前のラベル(ラベル名は何でもよい)を設定する。さらに、OutLoopラベルを設定した処理を抜けたい部分に「break OutLoop」と書く。
実行すると、「break OutLoop」でOutLoopラベルが設定されたforループを抜けて、そのあとの「fmt.Println("#####")」まで実行される。

~~~
func main() {
	tick := time.Tick(100 * time.Millisecond)
	boom := time.After(500 * time.Millisecond)
OutLoop:         //for文にOutLoopラベルを作成する
	for {
		select {
		case <-tick:
			fmt.Println("tick.")
		case <-boom:
			fmt.Println("BOOM!")
			break OutLoop   //OutLoopラベルの範囲を抜ける
		default:
			fmt.Println("    .")
			time.Sleep(50 * time.Millisecond)
		}
	}
    fmt.Println("#####")
}

//以下のように出力される
    .
    .
tick.
    .
    .
tick.
    .
    .
tick.
    .
    .
tick.
    .
    .
BOOM!
#####
~~~

## 学習に使用した教材
・『入門】Golang基礎入門 + 各種ライブラリ + 簡単なTodoWebアプリケーション開発(Go言語)』M.A EduTech
https://www.udemy.com/course/golang-webgosql/?utm_medium=udemyads&utm_source=bene-msa&utm_campaign=responsive&utm_content=top-1&utm_term=general&msclkid=81e2f24a32cc185d275d953d60760226&couponCode=NEWYEARCAREERJP

・『シリコンバレー一流プログラマーが教える Goプロフェッショナル大全』酒井 潤 (著)
https://www.amazon.co.jp/%E3%82%B7%E3%83%AA%E3%82%B3%E3%83%B3%E3%83%90%E3%83%AC%E3%83%BC%E4%B8%80%E6%B5%81%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9E%E3%83%BC%E3%81%8C%E6%95%99%E3%81%88%E3%82%8B-Go%E3%83%97%E3%83%AD%E3%83%95%E3%82%A7%E3%83%83%E3%82%B7%E3%83%A7%E3%83%8A%E3%83%AB%E5%A4%A7%E5%85%A8-%E9%85%92%E4%BA%95-%E6%BD%A4/dp/4046070897