转换 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)