转换 VBScript 的 Eqv 运算符
Converting VBScript's Eqv Operator
如果你 google for PowerShell Eqv you currently will find the VBScript-to-Windows PowerShell Conversion Guide 在列表的顶部。然而,答案主要是技术帮助:
Eqv 运算符
定义:对两个表达式进行逻辑等价。
毫无疑问,Eqv 有其用途;我们只是不确定它是否有任何实际用途。尽管可能有 Windows PowerShell 等效项,但我们必须诚实:我们并没有认真寻找一个。
事实上,我在 VBScript 中多次使用 Eqv
运算符(也写为:A↔B
),如果它存在的话,我很可能会在 PowerShell 中使用它。
例子
我有一个群组列表 ("HR", "SAP", "!IT", "..."
)。如果用户是所有列出的组的成员,并且明确不是前面带有升级标记(如 "!IT"
,展开为:$Negate = $True
和 $Group = "IT"
)的组的成员应该完成一项特定的任务。脚本需要遍历组并在不满足组条件时立即中断迭代(以节省时间)。
这个命令应该是这样的:
If ($Negate -eqv (IsMember($Group))) {Break}
如何用最少的代码构建逻辑等价运算符?
如果从字面上理解定义,您可能已经看到实现逻辑等价操作的可能方法:
If ([Bool]$Expression1 -eq [Bool]$Expression2) {...}
但是,如果您仔细观察真相 table,您可能会注意到 Eqv
的结果与 Xor
操作的结果完全相反。
这意味着您还可以通过倒置 Xor
:
实现逻辑等价操作
If (!(Expression1 -xor $Expression2)) {...}
因为对 Xor
(整个运算或其中一个表达式)取反并不重要,您甚至可以将其简化为:
If (!Expression1 -xor $Expression2) {...}
检查
0..3 | ForEach {
$Expression1, $Expression2 = [Int]($_ / 2), [Int]($_ % 2)
New-Object PSObject -Property @{
Expression1 = [Bool]$Expression1
Expression2 = [Bool]$Expression2
Equivalence = !$Expression1 -xor $Expression2
}
} | Format-Table -AutoSize
真相Table
Expression1 Expression2 Equivalence
----------- ----------- -----------
False False True
False True False
True False False
True True True
注意: 在此解决方案中 $Null
表达式被视为 $False
。这不同于 VBScript Eqv
实现,但与包含 $Null
表达式的其他 PowerShell 运算符一致。例如VBScript语句:If 1 And vbNull Then msgbox "True" Else msgbox "False"
, returns True
其中PowerShell语句If (1 -and $Null) {"True"} Else {"False"}
, returns False
.
按位
如果您要查找按位 Eqv
运算符(如果存在,可能应该称为 -bEqv
),那么它将是:
$Equivalence = -bNot Expression1 -bXOr Expression2 # e.g.: -bNot 3 -bXOr 5 = -7 (-bAnd 0xF = 9)
如果你 google for PowerShell Eqv you currently will find the VBScript-to-Windows PowerShell Conversion Guide 在列表的顶部。然而,答案主要是技术帮助:
Eqv 运算符
定义:对两个表达式进行逻辑等价。
毫无疑问,Eqv 有其用途;我们只是不确定它是否有任何实际用途。尽管可能有 Windows PowerShell 等效项,但我们必须诚实:我们并没有认真寻找一个。
事实上,我在 VBScript 中多次使用 Eqv
运算符(也写为:A↔B
),如果它存在的话,我很可能会在 PowerShell 中使用它。
例子
我有一个群组列表 ("HR", "SAP", "!IT", "..."
)。如果用户是所有列出的组的成员,并且明确不是前面带有升级标记(如 "!IT"
,展开为:$Negate = $True
和 $Group = "IT"
)的组的成员应该完成一项特定的任务。脚本需要遍历组并在不满足组条件时立即中断迭代(以节省时间)。
这个命令应该是这样的:
If ($Negate -eqv (IsMember($Group))) {Break}
如何用最少的代码构建逻辑等价运算符?
如果从字面上理解定义,您可能已经看到实现逻辑等价操作的可能方法:
If ([Bool]$Expression1 -eq [Bool]$Expression2) {...}
但是,如果您仔细观察真相 table,您可能会注意到 Eqv
的结果与 Xor
操作的结果完全相反。
这意味着您还可以通过倒置 Xor
:
If (!(Expression1 -xor $Expression2)) {...}
因为对 Xor
(整个运算或其中一个表达式)取反并不重要,您甚至可以将其简化为:
If (!Expression1 -xor $Expression2) {...}
检查
0..3 | ForEach {
$Expression1, $Expression2 = [Int]($_ / 2), [Int]($_ % 2)
New-Object PSObject -Property @{
Expression1 = [Bool]$Expression1
Expression2 = [Bool]$Expression2
Equivalence = !$Expression1 -xor $Expression2
}
} | Format-Table -AutoSize
真相Table
Expression1 Expression2 Equivalence
----------- ----------- -----------
False False True
False True False
True False False
True True True
注意: 在此解决方案中 $Null
表达式被视为 $False
。这不同于 VBScript Eqv
实现,但与包含 $Null
表达式的其他 PowerShell 运算符一致。例如VBScript语句:If 1 And vbNull Then msgbox "True" Else msgbox "False"
, returns True
其中PowerShell语句If (1 -and $Null) {"True"} Else {"False"}
, returns False
.
按位
如果您要查找按位 Eqv
运算符(如果存在,可能应该称为 -bEqv
),那么它将是:
$Equivalence = -bNot Expression1 -bXOr Expression2 # e.g.: -bNot 3 -bXOr 5 = -7 (-bAnd 0xF = 9)