为什么空的 Powershell 散列 table 会在空数组的计算结果为 False 时计算为 True?
Why does an empty Powershell hash table evaluate to True when an empty array evaluates to False?
我正在 Powershell 4.0 中试验 True 和 False。以下是查看空数组和空哈希 table:
时的结果
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 时空散列 tables 的计算结果为 True?
根据 Powershell 文档 About Comparison Operators:
When the input is a collection of values, the comparison operators
return any matching values. If there are no matches in a collection,
comparison operators do not return anything.
因此我希望散列 table 和数组在它们为空时表现相同,因为它们都是集合。我希望两者都评估为 False,因为它们 return 与 if
子句无关。
这不是 True/False 的问题。您可以使用布尔运算符 $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
根据, Count
is a better test to see if a hashtable/array is empty.
不同的行为将与基本类型相关。
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语句的工作方式有关。以下是我(诚然不稳定)从多篇 Whosebug 帖子和外部链接中得到的理解。
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
属性 - .
$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 class 的 IsNullOrEmpty method 给出与 $null
不同的输出,我假设是因为这也依赖于 Length
。
if ([string]::IsNullOrEmpty($a)) > True
if ([string]::IsNullOrEmpty($h)) > False
我正在 Powershell 4.0 中试验 True 和 False。以下是查看空数组和空哈希 table:
时的结果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 时空散列 tables 的计算结果为 True?
根据 Powershell 文档 About Comparison Operators:
When the input is a collection of values, the comparison operators return any matching values. If there are no matches in a collection, comparison operators do not return anything.
因此我希望散列 table 和数组在它们为空时表现相同,因为它们都是集合。我希望两者都评估为 False,因为它们 return 与 if
子句无关。
这不是 True/False 的问题。您可以使用布尔运算符 $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
根据Count
is a better test to see if a hashtable/array is empty.
不同的行为将与基本类型相关。
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语句的工作方式有关。以下是我(诚然不稳定)从多篇 Whosebug 帖子和外部链接中得到的理解。
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
属性 -
$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 class 的 IsNullOrEmpty method 给出与 $null
不同的输出,我假设是因为这也依赖于 Length
。
if ([string]::IsNullOrEmpty($a)) > True
if ([string]::IsNullOrEmpty($h)) > False