【问题标题】:Weird Coalesce Behavior奇怪的合并行为
【发布时间】:2019-12-22 00:23:30
【问题描述】:

好的,最近我正在寻找一种在 PowerShell 中进行 null 合并的方法,结果遇到了这个帖子:Null coalescing in powershell。

我看到@Zenexer 的评论,很感兴趣。这是语法:

Clear-Host
#expected one
"Test 1: " + ("one", "two", 1 -ne $null)[0]
#expected two
"Test 2: " + ($null, "two", 1 -ne $null)[0]

这非常有效。然而,我和一位同事 (Walter Puckett) 非常感兴趣,并且对语法进行了更多挖掘,发现了一些真正的怪异之处。

在我进入奇怪之处之前,任何人都可以指出任何解释这种语法的文档吗?

## THE WEIRDNESS:

# it does not matter what the number is evidently
"Test 3: " + ($null, "two", 8675309 -ne $null)[0]

# reversing the comparison test breaks the coalesce
"Test 4: " + ($null, "two", $null -ne 1)[0]

# Moving the test into the middle of the array evidently cuts the array off
"Test 5: " + ($null, 1 -ne $null, "two").Length

# Moving the test into the middle of the array evidently cuts the array off,
# UNLESS you wrap the test with parens
"Test 6: " + ($null, (1 -ne $null), "two").Length

# The number used in the test is returned for the array value at that index
"Test 7: " + ($null, $null, 8675309 -ne $null)[0]

# The number used in the test is returned for the array value at that index,
# UNLESS you wrap the test with parens
"Test 8: " + ($null, $null, (8675309 -ne $null))[0]

# wrapping the test with parens will break the coalesce
"Test 9: " + ($null, "two", (1 -ne $null))[0]

# if all elements are null, the default value will be the value on the left
# side of the test
"Test 10: " + ($null, $null, 123456789 -ne $null)[0]

# test with an object
$conn = New-Object System.Data.SqlClient.SqlConnection     
"Test 11: " + ($null, $conn, 1 -ne $null)[0].GetType()

经验教训:

  • 测试应该进入数组的最后一个元素
  • 不应使用括号包裹测试,因为它会破坏合并
  • 默认值必须位于测试的左侧,或者硬编码为数组中倒数第二项
  • 我们使用数字和简单的对象测试进行了测试,因此它应该适用于任何类型的对象

【问题讨论】:

    标签: powershell


    【解决方案1】:

    这里有两个主要关注的文档主题:


    它的缺点是与你的工作方法进行空合并:

    • -ne $null 必须用作过滤器

    • 并且过滤器必须应用于整个数组

    这样,索引[0] 将返回输入数组中的第一个非空元素。

    由于可能不明显,让我指出,正如 about_Operator_Precedence 中所述:

    $null, 2, 3 -ne $null # returns array without $nulls: 2, 3
    

    被解析为:

    ($null, 2, 3) -ne $null
    

    显然数字是多少并不重要

    "Test 3: " + ($null, "two", 8675309 -ne $null)[0]

    测试 3 按预期工作:-ne $null 过滤掉了 $null 元素,因此索引 0 访问第一个非空元素。


    反转比较测试会破坏合并

    "Test 4: " + ($null, "two", $null -ne 1)[0]

    -ne 1 返回所有不是1 的元素,其中包括$null 元素;所以访问索引0 在这里返回$null。


    将测试移到数组的中间显然会切断数组

    "Test 5: " + ($null, 1 -ne $null, "two").Length

    $null, 1 -ne $null, "two" 与:(($null, 1) -ne $null), "two" 相同,因此您最终会得到一个 2 元素数组,其第一个元素是仅包含 1 的单元素数组,该数组中唯一的非空元素;也就是说,结果数组是:(, 1), "two"


    所有其他测试只是上述测试的变体。

    【讨论】:

    • TYVM @mklement0,看到它记录在运算符优先级文档中让我感觉更好,但这可能是我希望找到它的最后一个地方。 :)
    • 很高兴听到它有帮助,@SpaceGhost440。 PowerShell 中的运算符优先级可能很棘手,尤其是因为有太多运算符,包括 ,,数组构造运算符本身。
    猜你喜欢
    • 1970-01-01
    • 2023-03-16
    • 2019-12-13
    • 2017-08-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-17
    • 1970-01-01
    相关资源
    最近更新 更多