2017-09-06 8 views
2

En this about page, il y a un bloc de code (ci-dessous) qui montre la variable automatique $ForEach, mais il a aussi une syntaxe comme un sous-programme en batch. Je ne peux pas trouver de documentation sur le fonctionnement de ce morceau de code ou sur la structure du langage. Je crois que c'est un ajout à PowerShell v5, mais lire les notes de version ne m'a pas aidé non plus. Que représente :tokenLoop foreach ($token in $tokens)?about_Foreach Exemple: syntaxe de sous-routine cmd dans PowerShell?

function Get-FunctionPosition { 
    [CmdletBinding()] 
    [OutputType('FunctionPosition')] 
    param(
    [Parameter(Position = 0, Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)] 
    [ValidateNotNullOrEmpty()] 
    [Alias('PSPath')] 
    [System.String[]] 
    $Path 
) 

    process { 
    try { 
     $filesToProcess = if ($_ -is [System.IO.FileSystemInfo]) { 
     $_ 
     } 
     else { 
     Get-Item -Path $Path 
     } 
     foreach ($item in $filesToProcess) { 
     if ($item.PSIsContainer -or $item.Extension -notin @('.ps1', '.psm1')) { 
      continue 
     } 
     $tokens = $errors = $null 
     $ast = [System.Management.Automation.Language.Parser]::ParseFile($item.FullName, ([REF]$tokens), ([REF]$errors)) 
     if ($errors) { 
      Write-Warning "File '$($item.FullName)' has $($errors.Count) parser errors." 
     } 
     :tokenLoop foreach ($token in $tokens) { 
      if ($token.Kind -ne 'Function') { 
       continue 
      } 
      $position = $token.Extent.StartLineNumber 
      do { 
      if (-not $foreach.MoveNext()) { 
       break tokenLoop 
      } 
      $token = $foreach.Current 
      } until ($token.Kind -in @('Generic', 'Identifier')) 
      $functionPosition = [pscustomobject]@{ 
      Name  = $token.Text 
      LineNumber = $position 
      Path  = $item.FullName 
      } 
      Add-Member -InputObject $functionPosition -TypeName FunctionPosition -PassThru 
     } 
     } 
    } 
    catch { 
     throw 
    } 
    } 
} 
+3

Vous mélangez deux constructions; voir [about_break] (https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_break?view=powershell-5.1) –

+0

Donc, c'est une étiquette pour une boucle à utiliser avec la déclaration de rupture. Savez-vous si cela a toujours fait partie de PowerShell ou si vous avez ajouté une version spécifique @JeffZeitlin? Je n'ai pas pu trouver "ceci a été ajouté dans X" sur la page à propos de. – TheIncorrigible1

+1

@ TheIncorrigible1 Les étiquettes ont été dans ps depuis au moins v 3.0 (ils sont décrits dans la spécification de langue v3) –

Répondre

4

Dans PowerShell version 3.0 ou plus récente (au moins depuis la version 2.0), les types d'instructions suivants sont éventuellement marqué:

  • switch
  • foreach
  • for
  • while
  • do

Maintenant, qu'est-ce que cela signifie? Cela signifie que vous pouvez fournir un nom d'étiquette en tant qu'argument à l'instruction break ou continue dans le corps de votre instruction étiquetée et que le contrôle de flux s'applique à l'instruction indiquée par l'étiquette.

Considérons cet exemple:

foreach($Name in 'Alice','Bob','Charlie'){ 
    switch($Name.Length){ 
     {$_ -lt 4} { 
      # We don't have time for short names, go to the next person 
      continue 
     } 
     default { 
      Write-Host "$Name! What a beautiful name!" 
     } 
    } 

    Write-Host "Let's process $Name's data!" 
} 

Vous pourriez attendre le « Let processus de [...] » chaîne à apparaître seulement deux fois, puisque nous continue dans le cas de Bob, mais depuis la déclaration parent immédiat est un switch, il ne s'applique pas réellement à l'instruction foreach.

Maintenant, si nous pouvons affirmer explicitement que nous voulons continuer la boucle foreach plutôt que l'instruction switch, nous pouvons éviter que:

:outer_loop 
foreach($Name in 'Alice','Bob','Charlie'){ 
    switch($Name.Length){ 
     {$_ -lt 4} { 
      # We don't have time for short names, go to the next person 
      continue outer_loop 
     } 
     default { 
      Write-Host "$Name! What a beautiful name!" 
     } 
    } 

    Write-Host "Let's process $Name's data!" 
} 

maintenant la déclaration continue continue en fait la boucle plutôt que l'interrupteur.

Très utile lorsque vous avez des constructions de boucles imbriquées.


Les étiquettes sont brièvement discutées conjointement avec break dans une instruction while dans le about_Break help topic

+0

IIRC, boucles étiquettes était dans PowerShell depuis v1.Ils fonctionnent certainement en v2. Bien que je n'ai pas v1 pour le confirmer ici. – PetSerAl