code

Foreach-Object에서 'continue'가 'break'처럼 작동하는 이유는 무엇입니까?

starcafe 2023. 4. 8. 09:04
반응형

Foreach-Object에서 'continue'가 'break'처럼 작동하는 이유는 무엇입니까?

PowerShell 스크립트에서 다음을 수행하는 경우:

$range = 1..100
ForEach ($_ in $range) {
    if ($_ % 7 -ne 0 ) { continue; }
    Write-Host "$($_) is a multiple of 7"
}

예상되는 출력은 다음과 같습니다.

7 is a multiple of 7
14 is a multiple of 7
21 is a multiple of 7
28 is a multiple of 7
35 is a multiple of 7
42 is a multiple of 7
49 is a multiple of 7
56 is a multiple of 7
63 is a multiple of 7
70 is a multiple of 7
77 is a multiple of 7
84 is a multiple of 7
91 is a multiple of 7
98 is a multiple of 7

하지만 만약 내가 파이프라인을 사용하고ForEach-Object,continue파이프라인 루프를 탈출한 것 같아요

1..100 | ForEach-Object {
    if ($_ % 7 -ne 0 ) { continue; }
    Write-Host "$($_) is a multiple of 7"
}

한 잔 주시겠어요?continue- 아직 ForEach-Object를 하고 있는 동안에도 같은 행동을 해서 내 파이프라인을 해체할 필요가 없어?

를 사용하면 됩니다.return대신continue.이것.return에 의해 호출된 스크립트블록에서 반환됩니다.ForEach-Object따라서, 특정 반복에 있어서, 그것은 다음과 같이 시뮬레이션한다.continue고리를 틀어서.

1..100 | ForEach-Object {
    if ($_ % 7 -ne 0 ) { return }
    Write-Host "$($_) is a multiple of 7"
}

리팩터링을 할 때 주의해야 할 점이 있습니다.때때로 변환하고 싶을 때가 있다.foreach스테이트먼트를 사용하여 파이프라인에 블록하다ForEach-Objectcmdlet(에일리어스도 포함)foreach변환이 쉬워지고 실수도 쉬워집니다.)모든.continue를 다음과 같이 치환해야 합니다.return.

추신: 안타깝게도, 이 시스템을 시뮬레이트하는 것은 쉽지 않습니다.breakForEach-Object.

왜냐면For-Each오브젝트는 cmdlet이며 루프가 아닙니다.continue그리고.break해당되지 않습니다.

예를 들어 다음과 같습니다.

$b = 1,2,3

foreach($a in $b) {

    $a | foreach { if ($_ -eq 2) {continue;} else {Write-Host $_} }

    Write-Host  "after"
}

다음과 같이 출력됩니다.

1
after
3
after

왜냐하면continue는 foreach-object cmdlet이 아닌 외부 foreach 루프에 적용됩니다.루프가 없는 경우, 가장 바깥쪽의 레벨입니다.따라서 다음과 같이 동작하는 인상을 줍니다.break.

그럼 어떻게 하면continue- 같은 행동?한 가지 방법은 물론 Where-Object입니다.

1..100 | ?{ $_ % 7  -eq 0} | %{Write-Host $_ is a multiple of 7}

단순.else스테이트먼트를 사용하면 다음과 같이 동작합니다.

1..100 | ForEach-Object {
    if ($_ % 7 -ne 0 ) {
        # Do nothing
    } else {
        Write-Host "$($_) is a multiple of 7"
    }
}

또는 단일 파이프라인:

1..100 | ForEach-Object { if ($_ % 7 -ne 0 ) {} else {Write-Host "$($_) is a multiple of 7"}}

그러나 보다 우아한 솔루션은 테스트를 뒤집고 성공만을 위한 출력을 생성하는 것입니다.

1..100 | ForEach-Object {if ($_ % 7 -eq 0 ) {Write-Host "$($_) is a multiple of 7"}}

또 다른 대안은 일종의 해킹이지만, 한 번 실행되는 루프에 블록을 감쌀 수 있습니다.그와 같이,continue원하는 효과를 가져옵니다.

1..100 | ForEach-Object {
    for ($cont=$true; $cont; $cont=$false) {
        if ($_ % 7 -ne 0 ) { continue; }
        Write-Host "$($_) is a multiple of 7"
    }
}

언급URL : https://stackoverflow.com/questions/7760013/why-does-continue-behave-like-break-in-a-foreach-object

반응형