奇怪的合并行为

Spa*_*440 2 powershell

好的,最近我正在寻找一种在 PowerShell 中空合并的方法,我遇到了这篇文章:在 powershell 中空合并。

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

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

这完美地工作。然而,我和一位同事 (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()
Run Code Online (Sandbox Code Playgroud)

得到教训:

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

mkl*_*nt0 5

这里有两个主要感兴趣的文档主题:


简而言之,对于与您的工作方法进行空合并:

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

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

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

由于它可能不明显,让我指出,如记录在about_Operator_Precedence:

$null, 2, 3 -ne $null # returns array without $nulls: 2, 3
Run Code Online (Sandbox Code Playgroud)

被解析为:

($null, 2, 3) -ne $null
Run Code Online (Sandbox Code Playgroud)

显然数字是多少并不重要

"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"


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