考虑这段代码
"Type: array"
$v = @()
" -eq `$null: $($v -eq $null)"
" -ne `$null: $($v -ne $null)"
"Type: string"
$v = ''
" -eq `$null: $($v -eq $null)"
" -ne `$null: $($v -ne $null)"
产生以下结果:
Type: array
-eq $null:
-ne $null:
Type: string
-eq $null: False
-ne $null: True
为什么-eq
和-ne
的行为符合预期的空字符串,但对空数组求值为null或为空?
更重要的是,您如何区分$null
和空数组?
答案 0 :(得分:6)
答案 1 :(得分:2)
@ mjolinor answer是问题(1)的简单而正确的答案。这个答案实际上会导致另外两个问题。
about_Comparison_Operators声明如下:
当输入是值的集合时, 比较运算符返回任何匹配值。如果没有比赛 在集合中,比较运算符不会返回任何内容。
这意味着行为取决于Powershell对"集合"的定义。在这种背景下。 Pipeline unrolling has a similar dependence on the definition of "collection".这也意味着交换比较运算符的LHS和RHS可能会产生重大差异。
因此,除了最初的问题2之外,我们还有两个未回答的问题:
$null
和空数组?这三个剩下的问题都可以使用本答案末尾的脚本凭经验回答。
CollectionType x_eq_Null coll_LHS_result Null_eq_x coll_RHS_result
-------------- --------- --------------- --------- ---------------
string False Boolean False Boolean
ArrayList {} Object[] False Boolean
Hashtable False Boolean False Boolean
Queue {} Object[] False Boolean
SortedList False Boolean False Boolean
Stack {} Object[] False Boolean
Dictionary False Boolean False Boolean
List {} Object[] False Boolean
Null True Boolean True Boolean
boolean False Boolean False Boolean
int32 False Boolean False Boolean
char False Boolean False Boolean
我们可以使用该表来回答问题:
- 如何区分
醇>$null
和空数组?
将集合移动到运算符的RHS(例如$null -eq @()
)会为所有测试类型生成一个布尔值(请参阅列coll_RHS_result
)。这意味着$null -ne @()
按预期评估为True,这使我们能够可靠地检测$null
和@()
之间的差异。
- Powershell比较运营商将哪些类型视为集合?
醇>
coll_LHS_result
为Object[]
的每种类型。
- 交换比较运算符的LHS和RHS会产生影响吗?
醇>
确实如此。将集合放在运算符的LHS上会产生一个数组。将标量放在运算符的LHS上会产生一个布尔值。
('string', ('')),
('ArrayList', (New-Object System.Collections.ArrayList)),
('Hashtable', (New-Object System.Collections.Hashtable)),
('Queue', (New-Object System.Collections.Queue)),
('SortedList', (New-Object System.Collections.SortedList)),
('Stack', (New-Object System.Collections.Stack)),
('Dictionary', (New-Object "System.Collections.Generic.Dictionary``2[System.String,int32]")),
('List', (New-Object System.Collections.Generic.List``1[int32])),
('Null', ($null)),
('boolean', ($false)),
('int32', ([int32]0)),
('char', ([char]"`0")) |
% {
New-Object PSObject -Property @{
CollectionType = $_[0]
x_eq_Null = $_[1] -eq $null
coll_LHS_result = ($_[1] -eq $null).GetType().Name
Null_eq_x = $null -eq $_[1]
coll_RHS_result = ($null -eq $_[1]).GetType().Name
}
} |
select CollectionType,x_eq_Null,coll_LHS_result,Null_eq_x,coll_RHS_result |
ft -AutoSize