中断について
概要
Foreach、For、While、Do、Switch の各ステートメントをすぐに終了するために使用できるステートメントについて説明します。
詳細説明
Foreach、For、While ループなどのループ内に Break ステートメントが含まれている場合、Break ステートメントによって PowerShell が直ちにループを終了します。 スイッチコンストラクトでは、Break によって PowerShell が切り替えコードブロックを終了します。
Break ステートメントには、埋め込みループを終了できるラベルを含めることができます。 ラベルでは、スクリプトで Foreach、For、While などの loop キーワードを指定できます。
次の例では、Break ステートメントを使用して For ステートメントを終了する方法を示します。
for($i=1; $i -le 10; $i++) {
Write-Host $i
break
}
この例では、$i 変数が1と等しい場合、Break ステートメントは For ループを終了します。 $I が10を超えるまで For ステートメントが True と評価された場合でも、PowerShell は For ループの初回実行時に break ステートメントに到達します。
内部条件を満たす必要があるループでは、Break ステートメントを使用するのが一般的です。 次の Foreach ステートメントの例を考えてみましょう。
$i=0
$varB = 10,20,30,40
foreach ($val in $varB) {
$i++
if ($val -eq 30) {
break
}
}
Write-Host "30 was found in array position $i"
この例では、Foreach ステートメントは $varB 配列を反復処理します。 コードブロックが実行されるたびに、$i 変数が1ずつインクリメントされます。 If ステートメントは、ループの最初の2回の実行で False と評価されます。 ループが3回実行されたとき、$i が3で、$val 変数が30に等しい。 この時点で、Break ステートメントが実行され、Foreach ループが終了します。
Foreach ループから分割するのと同じ方法で、他のループステートメントを中断します。 次の例では、DivideByZeroException 例外がトラップステートメントを使用してトラップされた場合に、Break ステートメントによって While ステートメントが終了します。
$i = 3
while ($true) {
trap [DivideByZeroException] {
Write-Host 'divide by zero trapped'
break
}
1 / $i--
}
Break ステートメントには、ラベルを含めることができます。 Break キーワードをラベルと共に使用すると、PowerShell は、現在のループを終了するのではなく、ラベルが付けられたループを終了します。 ラベルの構文は次のとおりです (この例では、While ループでラベルを示しています)。
: myLabel while ( <condition>
) { <statement list>
}
ラベルは、コロンの後に割り当てた名前を付けたものです。 ラベルは、ステートメント内の最初のトークンである必要があります。また、While の後にループキーワードを指定する必要があります。
PowerShell では、Foreach、For、While などのループキーワードのみがラベルを持つことができます。
Break は、ラベルが付けられたループから実行されます。 埋め込みループでは、Break キーワードが単独で使用される場合とは異なる結果になります。 このスケマティックの例には、For ステートメントを含む While ステートメントがあります。
:myLabel while (<condition 1>) {
for ($item in $items) {
if (<condition 2>) {
break myLabel
}
$item = $x # A statement inside the For-loop
}
}
$a = $c # A statement after the labeled While-loop
Condition 2 が True と評価された場合、スクリプトの実行は、ラベル付けされたループの後のステートメントまでスキップされます。 この例では、実行はステートメント "$a = $c" で再び開始されます。
次のスケマティックの例に示すように、多数のラベル付きループを入れ子にすることができます。
:red while (<condition1>) {
:yellow while (<condition2>) {
while (<condition3>) {
if ($a) {break}
if ($b) {break red}
if ($c) {break yellow}
}
Write-Host "After innermost loop"
}
Write-Host "After yellow loop"
}
Write-Host "After red loop"
$B 変数が True と評価されると、"red" というラベルが付いたループの後にスクリプトの実行が再開されます。 $C 変数が True と評価された場合、"黄色" というラベルが付いたループの後に、スクリプトコントロールの実行が再開されます。
$A 変数が True と評価された場合、最も内側のループの後に実行が再開されます。 ラベルは必要ありません。
PowerShell では、ラベルの実行を再開する距離を制限しません。 ラベルは、スクリプトと関数呼び出しの境界を越えて制御を渡すこともできます。
Break キーワードは、スイッチコンストラクトを離れるために使用されます。 たとえば、次の Switch ステートメントでは、Break ステートメントを使用して、最も具体的な条件をテストしています。
$var = "word2"
switch -regex ($var) {
"word2" {
Write-Host "Exact" $_
break
}
"word.*" {
Write-Host "Match on the prefix" $_
break
}
"w.*" {
Write-Host "Match on at least the first letter" $_
break
}
default {
Write-Host "No match" $_
break
}
}
この例では、$var 変数が作成され、文字列値 "word2" に初期化されます。 Switch ステートメントでは、Regex クラスを使用して、変数の値を最初に "word2" という用語に一致させます。 (Regex クラスは、フレームワーククラス Microsoft .NET 正規表現です)。Switch ステートメントの変数の値と最初のテストが一致するので、Switch ステートメントの最初のコードブロックが実行されます。
PowerShell が最初の Break ステートメントに到達すると、Switch ステートメントが終了します。 この例から4つの Break ステートメントを削除すると、4つの条件がすべて満たされます。 この例では、最も限定的な条件が満たされたときに、break ステートメントを使用して結果を表示します。