次の方法で共有


about_Break

簡単な説明

現在の制御ブロックを終了する方法を提供する break ステートメントについて説明します。

詳細な説明

break ステートメントは、現在の制御ブロックを終了する方法を提供します。 制御ブロックの後の次のステートメントで実行が続行されます。 このステートメントはラベルをサポートしています。 ラベルは、スクリプト内のステートメントに割り当てる名前です。

ループでの break の使用

foreachfordowhile ループなどのbreak ステートメントがループ内に表示されると、PowerShell は直ちにループを終了します。

breakステートメントには、埋め込みループを終了できるラベルを含めることができます。 ラベルでは、スクリプト内の任意のループ キーワード ( foreachforwhileなど) を指定できます。

次の例は、 break ステートメントを使用して for ステートメントを終了する方法を示しています。

for($i=1; $i -le 10; $i++) {
   Write-Host $i
   break
}

この例では、$i変数が 1 の場合、break ステートメントは for ループを終了します。 for ステートメントは、$iが 10 より大きくなるまでTrue と評価されますが、for ループが初めて実行されるときに、PowerShell は break ステートメントに到達します。

内部条件を満たす必要があるループで break ステートメントを使用する方が一般的です。 次の foreach ステートメントの例を考えてみましょう。

$i=0
$varB = 10,20,30,40
foreach ($val in $varB) {
  if ($val -eq 30) {
    break
  }
  $i++
}
Write-Host "30 was found in array index $i"

この例では、 foreach ステートメントは $varB 配列を反復処理します。 if ステートメントは、ループが実行された最初の 2 回だけ False に評価され、変数$iが 1 ずつインクリメントされます。 3 回目のループの実行では、 $i は 2、 $val 変数は 30 になります。 この時点で、 break ステートメントが実行され、 foreach ループが終了します。

ループ内でのラベル付き break の使用

breakステートメントにはラベルを含めることができます。 ラベルと共に break キーワードを使用すると、PowerShell は現在のループを終了するのではなく、ラベル付きループを終了します。 ラベルはコロンの後に、割り当てる名前が続きます。 ラベルはステートメントの最初のトークンである必要があり、その後にループ キーワード ( 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

条件 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 に評価された場合、"yellow" というラベルの付いたループの後にスクリプト コントロールの実行が再開されます。

$a変数が True に評価された場合、最も内側のループの後に実行が再開されます。 ラベルは必要ありません。

PowerShell では、ラベルが実行を再開できる期間は制限されません。 ラベルは、スクリプトと関数呼び出しの境界を越えて制御を渡すことさえできます。

switch ステートメントでのbreakの使用

switch構造体では、breakによって PowerShell が switch コード ブロックを終了します。

break キーワードは、switch コンストラクトを残すために使用されます。 たとえば、次の 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 という用語と照合します。 変数値と switch ステートメントの最初のテストが一致するため、 switch ステートメントの最初のコード ブロックが実行されます。

PowerShell が最初の break ステートメントに到達すると、 switch ステートメントが終了します。 この例から 4 つの break ステートメントが削除されると、4 つの条件がすべて満たされます。 この例では、 break ステートメントを使用して、最も具体的な条件が満たされたときに結果を表示します。

trap ステートメントでのbreakの使用

trap ステートメントの本体で実行された最後のステートメントがbreak場合、エラー オブジェクトは抑制され、例外が再スローされます。

次の例では、trap ステートメントを使用してトラップされるDivideByZeroException例外を作成します。

function test {
  trap [DivideByZeroException] {
    Write-Host 'divide by zero trapped'
    break
  }

  $i = 3
  'Before loop'
  while ($true) {
     "1 / $i = " + (1 / $i--)
  }
  'After loop'
}
test

例外時に実行が停止していることに注意してください。 After loopに到達することはありません。 例外は、 trap の実行後に再スローされます。

Before loop
1 / 3 = 0.333333333333333
1 / 2 = 0.5
1 / 1 = 1
divide by zero trapped
ParentContainsErrorRecordException:
Line |
  10 |       "1 / $i = " + (1 / $i--)
     |       ~~~~~~~~~~~~~~~~~~~~~~~~
     | Attempted to divide by zero.

ループ、switch、または外部でbreakを使用しないでください。trap

breakを直接サポートするコンストラクト (ループ、switchtrap) の外部で使用すると、PowerShell は呼び出し履歴外側のコンストラクトを検索します。 外側のコンストラクトが見つからない場合、現在の実行空間は静かに終了します。

つまり、それをサポートする外側のコンストラクトの外部で誤って break を使用する関数とスクリプトは、 callersを誤って終了する可能性があります。

ForEach-Object スクリプト ブロックなど、パイプライン break内でbreakを使用すると、パイプラインが終了するだけでなく、実行空間全体が終了する可能性があります。

関連項目