Почему происходит выполнение цикла do / before со значениями, начинающимися с 1? - PullRequest
4 голосов
/ 22 июня 2019

Построил систему меню, которая по большей части работает нормально, но я столкнулся со странной ошибкой проверки, и я ломаю голову над тем, почему эта функция сбрасывается, когда вы отвечаете «11» (или действительно любым числом, начинающимся сс 1)

function Get-MenuSelection {

    $totalOptions = 2

    do {
        $input = Read-Host "[1 <-> $totalOptions | (Q)uit - FIRST]"
        while (!$input) {
            $input = Read-Host "[1 <-> $totalOptions | (Q)uit - LOOP]"
        }

    } until ($input -lt $totalOptions -or $input -eq $totalOptions -or $input -eq "q")

Write-Host "exiting"
}

Get-MenuSelection

Вывод, который я получаю:

./wtf.ps1
[1 <-> 2 | (Q)uit - FIRST]: 
[1 <-> 2 | (Q)uit - LOOP]: 
[1 <-> 2 | (Q)uit - LOOP]: test
[1 <-> 2 | (Q)uit - FIRST]: 22
[1 <-> 2 | (Q)uit - FIRST]: 9090
[1 <-> 2 | (Q)uit - FIRST]: 11
exiting

Я явно делаю что-то не так, но просто не могу понять, что.

Решение

Для тех, кто читает это некоторое время в будущем, я закончил с этим - я решил отказаться от опций 'q', так как это просто слишком усложняло логику.Спасибо @AdminofThings и @ mklement0 за ввод.Ценится.

function Get-MenuSelection {
    param (
        $output 
    )

    [int]$totalOptions = $output.Count
    do {
        try { [int]$answer = Read-Host "Options: [1 <-> $totalOptions]" }
        catch { }

        if ($answer -eq "0" -or $answer -gt $totalOptions) { 
            Write-Host "Invalid input detected. Ctrl+C to quit." 
        }
    } while ($answer -gt $totalOptions -or !$answer)

    $returnedAnswer = "menu_$answer"
    return $returnedAnswer
}

1 Ответ

4 голосов
/ 22 июня 2019

Поскольку $input является автоматической / зарезервированной переменной, ваш код не будет выполняться должным образом. $input, вероятно, приведет к пустому значению во время поиска.

Если мы теоретически предполагаем, что $input заменено чем-то, что не зарезервировано, то соответствующая проблема здесь - $input - строка, а $totaloptions - int. Когда PowerShell сталкивается с операцией сравнения, и обе стороны сравнения не соответствуют типам, он пытается преобразовать тип правой стороны (RHS), чтобы соответствовать левой стороне (LHS). Чтобы обойти это, вам нужно либо разыграть $input как [int], либо принести $totaloptions в LHS.

until ([int]$input -lt $totalOptions -or $input -eq $totalOptions -or $input -eq "q")
# OR
until ($totalOptions -gt $input -or $input -eq $totalOptions -or $input -eq "q")

Пример вашей ситуации:

#Unexpected Outcome
> [string]11 -lt [int]2
True

#Expected Outcome
> [int]11 -lt [int]2
False

#Expected Outcome
> [int]2 -gt [string]11
False
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...