【问题标题】:Why does an empty Powershell hash table evaluate to True when an empty array evaluates to False?当空数组评估为 False 时,为什么空的 Powershell 哈希表评估为 True?
【发布时间】:2017-11-06 19:07:16
【问题描述】:

我正在 Powershell 4.0 中试验 True 和 False。以下是查看空数组和空哈希表时的结果:

PS C:\Users\simon> $a = @()    
PS C:\Users\simon> if ($a) { Write-Host "True" } else { Write-Host "False" }
False

PS C:\Users\simon> $a = @{}    
PS C:\Users\simon> if ($a) { Write-Host "True" } else { Write-Host "False" }
True

为什么当空数组评估为 False 时,空哈希表评估为 True?

根据 Powershell 文档About Comparison Operators

当输入是值的集合时,比较运算符 返回任何匹配的值。如果集合中没有匹配项, 比较运算符不返回任何内容。

据此,我希望哈希表和数组在它们为空时的行为相同,因为它们都是集合。我希望两者都评估为 False ,因为它们没有返回任何 if 子句。

【问题讨论】:

  • 哈希表不是值的集合。它是具有键和值属性的字典条目的集合。我不希望能够对哈希表使用比较运算符,因为它不是一个连贯的表达式。您是否在测试键名或值?
  • @mjolinor:目前我只是在做实验。在过去,我使用过if ($a) { ... } 的测试来检查数组是否有元素。我以为我可以用哈希表做类似的事情,当哈希表表现出不同的行为时我感到很惊讶。

标签: powershell powershell-4.0


【解决方案1】:

这不是真假问题。您可以使用布尔运算符$true$false 对此进行测试。我使用$h 作为空哈希表@{}

PS C:\> $a = @()
PS C:\> $h = @{}
PS C:\> if ($a -eq $true) { Write-Host "True" } else { Write-Host "False" }
False

if ($h -eq $true)    >  False
if ($a -eq $false)   >  False
if ($h -eq $false)   >  False

也不等于自动变量$null

if($a -eq $null)     >  False
if($h -eq $null)     >  False

根据iRon's linkCount 是查看哈希表/数组是否为空的更好测试。 Related Length

不同的行为将与基本类型有关。

PS C:\> $a.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Object[]                                 System.Array

PS C:\> $h.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Hashtable                                System.Object

这与if 语句的工作方式和Length 属性AFAICS 有关。以下是我对多个 StackOverflow 帖子和外部链接的理解(诚然是不稳定的)。


Get-Member 行为不同 - 请参阅 Mathias's explanation

$a | Get-Member            # Error - Get-Member : You must specify an object for the Get-Member cmdlet.
$h | Get-Member            # TypeName: System.Collections.Hashtable. Has Count method, no Length property
Get-Member -InputObject $a # TypeName: System.Object[]. Has Count method, has Length property

变量的Length 属性不同。但是哈希表没有 Length 属性 - see mjolinar's answer

$a.Length   > 0
$h.length   > 1

结合Ansgar's link 解释了if 语句中的不同行为,因为它似乎隐含地获取了Length 属性。它还允许我们这样做:

if ($a.Length -eq $true)    >  False
if ($h.Length -eq $true)    >  True

使用 [String] .Net 类的IsNullOrEmpty method$null 相比会产生不同的输出,我认为这是因为这也依赖于Length

if ([string]::IsNullOrEmpty($a))    > True
if ([string]::IsNullOrEmpty($h))    > False

【讨论】:

    猜你喜欢
    • 2015-03-15
    • 2022-01-10
    • 1970-01-01
    • 2015-03-22
    • 2014-02-16
    • 1970-01-01
    • 1970-01-01
    • 2012-03-06
    相关资源
    最近更新 更多