为什么此do / until循环以1开头的值退出?

时间:2019-06-22 17:21:03

标签: powershell

建立了一个菜单系统,该菜单系统在大多数情况下都可以正常工作,但是我遇到了一个奇怪的验证错误,我想知道为什么当您回答“ 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 个答案:

答案 0 :(得分:4)

由于$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