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

问题描述 投票:0回答:2
$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,它会返回 1b,而如果我输入 1d,它不会返回任何内容,为什么?
  2. 如果我在提示时输入 1b,它会返回 1b,而如果我输入 1,它会返回 1 和 1d,为什么?
  3. PowerShell 似乎由于某种原因解释了 switch 语句中的 d 比较值不同,为什么?

我注意到比较值的颜色不同(1 和 1d 更暗),所以我猜 PowerShell ISE 语法突出显示告诉我们它们受到了不同的对待。 4. 颜色的含义是什么(栗色/深红色或紫色 VS 紫色?

powershell switch-statement
2个回答
6
投票

在解释为什么

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

它只是意味着“使用

-eq
运算符将输入值与案例标签进行比较”。

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

结果是,与输入字符串

"1"
的比较结果相同 -
"1" -eq 1
"1" -eq 1d
都是 true,这要归功于 PowerShell 的 重载运算符

如果您进一步扩展选项,您将遇到同样的问题

1l
(
l
=
[long]
),并且,如果使用 PowerShell 7,最终会
1n
1s
1u
、和
1y

引用开关标签以避免 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 解释为数字修饰符的后缀。


1
投票

添加到Mathias的优秀答案

  • switch
    语句的分支条件决不应该允许使用裸词未加引号的标记充当字符串)。

    • 这相当于 PowerShell 两种基本解析模式参数模式表达式模式的不恰当混合。

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

  • -exact
    开关选择进入默认行为,并且鉴于此行为的非精确性质,其令人困惑的命名

© www.soinside.com 2019 - 2024. All rights reserved.