我在if语句中尝试了$psCustomObject.x -eq $null
和$null -eq $psCustomObject.x
这两种情况,只有后者通过了if。
为什么这样表现呢?似乎不合逻辑。
我的特定用例是一个json文件,其中包含多个环境的配置。环境的名称是对象中的关键,我的目标是在目标不存在的环境(可能是拼写错误)时通知用户,然后停止。
我不想使用! opreator,因为它具有极高的信息与代码比率-很容易忽略,但是却有很大的不同,因此,我通常不喜欢它。它还需要了解语言的工作原理(powershell不是静态类型的,我不希望读者需要了解什么是真理还是不真理)。这听起来可能很愚蠢,但是powershell不是我的主要语言,也不是我的同事的语言。可读性是我的关键因素。
答案 0 :(得分:3)
tl; dr
要使用$null
或-eq
与-ne
进行比较,请始终使$null
为LHS :
$null -eq $psCustomObject.x # NOT $psCustomObject.x -eq $null
操作数的顺序很重要,因为PowerShell中的比较运算符用作具有 array-valued LHS值的 filters 。
此外,即使与$null
以外的其他内容进行比较,由于隐式类型转换,操作数的顺序也可能很重要。
PowerShell的comparison operators, such as -eq
在设计上与数组值 LHS 的行为不同,因此重要的操作数放置在对于通常可交换的运算符
-eq
和-ne
。
使用标量 LHS (单个值),比较运算符返回布尔值 ({$True
或$False
表示比较结果。
' 2 ' -eq 2
执行 string 比较(将整数2
强制转换为字符串'2'
),因此返回$False
,而2 -eq ' 2 '
执行< em>整数比较(将字符串' 2 '
转换为[int]
),因此返回$True
。具有 数组值的LHS (是集合的LHS值),比较运算符返回数组 ([object[]]
),因为它用作过滤器 :运算符分别应用于输入数组的元素 ,返回的是操作为其返回$True
的那些元素的子数组。
请注意,从Windows PowerShell v5.1 / PowerShell Core 6.1.0开始,PowerShell仅支持将数组值操作数用作 LHS 操作数; RHS操作数必须为<标量> 标量>或被强制为1。 [1]
因此,在您的示例中, $null -eq $psCustomObject.x
和$psCustomObject.x -eq $null
是不可互换的,并测试不同的条件:
# Is the RHS $null?
# Whether the concrete RHS value is then a scalar or an array doesn't matter.
$null -eq $psCustomObject.x
# * If $psCustomObject.x is a scalar: is that scalar $null?
# * If $psCustomObject.x is an ARRAY:
# RETURN THE SUB-ARRAY OF ELEMENTS THAT ARE $null
$psCustomObject.x -eq $null
在布尔上下文中(例如在if
语句中)使用 时,数组,例如以数组值的LHS返回的数组,评估如下:向PetSerAl求助的帽子提示。
$False
。[bool] @(0)
与[bool] 0
实际上相同,即, $False
。$True
,而不考虑其元素的值(例如,[bool] ($False, $False)
和[bool] (, (, $False))
均为$True
。 注意:术语 array 在上面使用得比较宽松。严格来说,以上内容适用于实现[System.Collections.IList]
接口的任何类型的实例-请参见the source code。
除了数组之外,还包括[System.Collections.ArrayList]
和[System.Collections.Generic.List[<type>]]
之类的类型。
示例:两个比较在布尔上下文中的评估结果不同:
注意:
这个例子有些人为-请告诉我们是否有更好的例子。
运算符-ne
可以提供更简单的示例。
我无法为您描述的特定行为提供一个示例,其中$null -eq $psCustomObject.x
返回$True
,而$psCustomObject.x -eq $null
却没有。如果确实如此,请告诉我们具体的.x
值。
# Construct a custom object with an array-valued .x property that
# contains at least 2 $null values.
$psCustomObject = [pscustomobject] @{ x = @(1, $null, 2, $null) }
# $False, as expected: the value of .x is an array, and therefore not $null
[bool] ($null -eq $psCustomObject.x)
# !! $True, because because 2 elements in the input array (.x)
# !! are $null, so a 2-element array - ($null, $null) - is returned, which in a
# !! Boolean context is always $True.
[bool] ($psCustomObject.x -eq $null)
[1]在文档中,-replace
与比较运算符组合在一起,从技术上讲,其RHS是一个数组,但是此数组的元素本质上是标量操作数:要匹配的正则表达式,以及替换字符串。