Powershell switch 语句比较值 1d 不稳定,为什么?

Powershell switch statement comparison value 1d erractic, why?

$UserChoice = Read-Host "Enter # of tool you want to run"
switch -exact ($UserChoice) {
    1 {Write-Host 'You selected 1'}
    1a {Write-Host 'You selected 1a'}
    1b {Write-Host 'You selected 1b'}
    1c {Write-Host 'You selected 1c'}
    1d {Write-Host 'You selected 1d'}
}

前言:我知道解决方法是将比较值放在引号中,例如:'1d'我想知道为什么 PowerShell 的行为方式是为了学习。

  1. 如果我在提示符下输入 1b,它会 returns 1b 而如果我输入 1d,它 returns 什么都没有,为什么?
  2. 如果我在提示符下输入 1b,它是 returns 1b,而如果我输入 1,它是 returns 1 和 1d,为什么?
  3. PowerShell 似乎在解释 switch 语句比较值中的 d 时出于某种原因不同,为什么?

--编辑:我刚刚注意到比较值在视觉上是不同的颜色(1 和 1d 更暗)所以我猜 PowerShell ISE 语法高亮显示告诉我们它们受到了不同的对待。 4. 颜色是什么意思(maroon/dark-RedOrPurple VS 紫色?

在解释为什么 1d 标签是“特殊的”之前,我应该注意 -exact 模式(这是 switch 语句的默认比较模式)可能是有点误导。

它只是表示“使用 -eq 运算符将输入值与案例标签进行比较”。

1d 行为不同的原因是 PowerShell 无法将表达式 1d 识别为字符串 。相反,它将 d 解释为表示 [decimal] 类型的数字后缀,因此 case 标签值与您编写的 1.0$([decimal]1) 相同。

结果是,与输入字符串 "1" 的比较结果对于两者都是相同的 - "1" -eq 1"1" -eq 1d 都为真,这要归功于 PowerShell 的

如果您进一步扩展选项,您将遇到与 1ll = [long])相同的问题,并且,如果使用 PowerShell 7,最终 1n1s1u1y

引用开关标签以避免 PowerShell 将它们解析为数字表达式:

$UserChoice = Read-Host "Enter # of tool you want to run"
switch -exact ($UserChoice) {
    '1'  {Write-Host 'You selected 1'}
    '1a' {Write-Host 'You selected 1a'}
    '1b' {Write-Host 'You selected 1b'}
    '1c' {Write-Host 'You selected 1c'}
    '1d' {Write-Host 'You selected 1d'}
}

请参阅 about_Numeric_Literals 帮助主题以更全面地了解由 PowerShell 解释为数字修饰符的后缀。

添加到

  • 语句的分支条件永远不允许使用 裸词未引用 标记作为字符串).

    • 这相当于不恰当地混合了 PowerShell 的两个基本 parsing modes参数模式表达式模式.

      • 在表达式模式中 - 这是合适的应用方式 - 字符串 必须 被引用;例如,要将 字符串 与逐字值 1d 匹配,它必须表示为 '1d',这可以消除它与 数字文字 1d,一个[decimal].
    • 请参阅 GitHub issue #3668 进行讨论。

  • -exact 开关选择进入 默认 行为,并且,给定 non-exact 这种行为的本质是 容易混淆的名称