$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 和 1d 更暗),所以我猜 PowerShell ISE 语法突出显示告诉我们它们受到了不同的对待。 4. 颜色的含义是什么(栗色/深红色或紫色 VS 紫色?
在解释为什么
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 解释为数字修饰符的后缀。
添加到Mathias的优秀答案:
switch
语句的分支条件决不应该允许使用裸词(未加引号的标记充当字符串)。
这相当于 PowerShell 两种基本解析模式、参数模式和表达式模式的不恰当混合。
1d
匹配,它必须表示为 '1d'
,这可以消除它与 数字文字 1d
、[decimal]
.请参阅 GitHub 问题 #3668 进行讨论。
-exact
开关选择进入默认行为,并且鉴于此行为的非精确性质,其令人困惑的命名。