Как я могу использовать выключатели? - PullRequest
0 голосов
/ 18 мая 2018

Это предназначено, чтобы помочь всем, кто сталкивается с проблемами при понимании и использовании оператора switch, включая использование переключателей внутри циклов, которые часто могут быть причиной отключения для пользователей PowerShell.

У меня есть вопросы:

  • Как использовать различные аргументы и случаи, поддерживаемые коммутатором?
    • -Exact, -Regex, -Wildcard, -CaseSensitive, -File
    • string, number, variable, {expression}
  • Почему break или continue не работает в моем операторе case в цикле?

    while ($true) {
        switch ($eval) {
            'some condition' { continue }
            default {
                break
            }
        }
    }
  • У меня естьdefault case, но он ничего не делает?

    switch ($eval) {
        'default' { 'this should do a thing!' }
    }

1 Ответ

0 голосов
/ 18 мая 2018

Существует множество вариантов использования оператора switch, но в конечном итоге они делают код более читабельным, чем большая цепочка if-elseif-else.

A switch принимает условие (или массив условий), и пытается сопоставить его с случаями, предоставленными автором.Это условие может принимать любое значение.

Важное замечание о переключателях PowerShell: , поскольку они могут принимать массив условий, они являются функциональными циклами, поэтому их можно пометить (:mySwitch switch ()) и break / continue ключевые слова работают против них.Аргумент будет оцениваться для каждого случая, если он не встречается в операторе break или continue, а default применяется только тогда, когда не найдено ни одного случая.


  • Как использоватьразличные аргументы и случаи, поддерживаемые коммутатором?

Коммутаторы анализируют файл за строкой при использовании параметра -File.В этом сценарии использования он в основном выполняется switch (Get-Content -Path $filePath) вместо передачи ему условия:

switch -File $filePath {

Четыре аргумента влияют на соответствие string вариантов: -Exact (по умолчанию), -Regex,-Wildcard (эти три исключают друг друга, используется последний в строке) и, наконец, -CaseSensitive.Каждый из этих аргументов похож на операторы сравнения -eq, -match и -like.-CaseSensitive заставляет их функционировать как -ceq, -cmatch и -clike. Если аргумент не является строкой, к нему применяются , а не . Эти аргументы передаются перед условием:

switch -Regex -CaseSensitive ($eval) {

или

switch -Wildcard -File C:\Temp\myfile.txt {

Мне кажется, что string совпадение должно быть достаточно очевидным, учитывая мое вышеупомянутое описание, относящееся к операторам сравнения, поэтому я не буду подробно их рассматривать.

У меня не было большого применения для случаев $variableи они не очень хорошо задокументированы.Пытаясь исследовать это для целей этого ответа, я столкнулся с замороженной консолью при попытке сравнить с [pscustomobject] типами, чтобы YMMV.

Number поддерживал десятичные числа, целые числа со знаком и без знака, например:

switch (1.3) {
    1.3 { 'this' }
    default { 'that' }
}
# "this"

switch (-5) {
    -5 { 'that' }
    default { 'this' }
}
# "that"

Я проверил это с double, int и uint64.

Последний поддерживаемый случай - expression и один из моих любимых.Когда вы передаете выражение для оценки коммутатором, оно похоже на работу с конвейером.Вы получаете доступ к объекту с помощью $_ (или $PSItem), и его члены доступны для доступа, как обычно.Пример:

switch (Get-WmiObject -Class Win32_OperatingSystem) {
    {$PSItem.Caption -like '*server*'} {
        "You're on a server OS!"
    }
    {$PSItem.Organization} { # truthy evaluation
        "You're part of organization: $($PSItem.Organization)!"
    }
    default {
        "This can't possibly fail!"
    }
}

  • Почему break или continue не работает в моем операторе case в цикле?

Посколькуswitch работает как цикл, эти ключевые слова работают против блока switch вместо инкапсулирующего цикла.Чтобы обойти это ограничение, вам нужно использовать метки цикла:

:myLoop while ($true) {
    :mySwitch switch ($eval) {
        'some condition' { continue }
        default {
            break
        }
    }
}

В обоих случаях это будет break или continue switch, а не while.Для того, чтобы иметь контроль, вам нужно указать метку, которую вы назначаете, например:

:myLoop while ($true) {
    :mySwitch switch ($eval) {
        #if $eval is an array, goes to the next iteration
        'some condition' { continue mySwitch } 
        default {
            break myLoop
        }
    }
}

  • У меня есть default case, но он ничего не делает?

Этот сводится к тому, чтобы быть опечаткой.default - это ключевое слово , а если у вас 'default', это оценка string.Так что в примере исправьте это, удалив кавычки, окружающие ключевое слово default .

switch ($eval) {
    default { 'this now does a thing!' }
}
...