0

PowerShell 7 最近将Null-conditional ( ?.) 运算符移出实验阶段。在玩弄它并阅读上面链接中的示例时,我想我理解它是如何工作的。在下面的示例中,provided$a不是 null 并且有一个名为PropName它的属性,它将返回值,$a.PropName否则返回 null。:

$a = @{ PropName = 100 }
${a}?.PropName # ==> 100

但是,我不明白为什么我会使用新的空条件运算符而不是使用点 ( .) 访问对象属性。下面的示例以两种方式呈现相同的内容,并且不会抛出或显式抑制任何错误:

@{ PropName = 100 },
@{ PropNumber = 8675309 } | Foreach-Object {
  Write-Host ( $null -ne $_.PropName ? "PropName has a value of $($_.PropName)" : 'PropName is $null' )
}

# 1st iteration ==> PropName has a value of 100
# 2nd iteration ==> PropName is $null

空条件(注意细微的变化)

@{ PropName = 100 },
@{ PropNumber = 8675309 } | Foreach-Object {
  Write-Host ( $null -ne ${_}?.PropName ? "PropName has a value of $(${_}?.PropName)" : 'PropName is $null' )
}

# 1st iteration ==> PropName has a value of 100
# 2nd iteration ==> PropName is $null

所以,我知道什么时候应该使用它,但是 PowerShell 已经有了一个语法更简单的解决方案。说白了,这个算子的意义何在?除了上面链接的内容之外,我找不到关于该运算符的太多文档,并且我假设一定有我遗漏的东西。数组 ( ) 有一个类似的运算符,?[]可以有条件地返回数组元素,如果索引超出范围,则返回 $null,但同样,$null如果您超出数组范围并尝试访问属性,PowerShell 已经返回且没有错误。

4

1 回答 1

0

提交后大约 30 秒,我意识到了差异。我上面的测试只测试属性成员,没有考虑方法或严格模式。但与其删除问题,我认为解释这一点是有价值的。

默认情况下,属性在对象上不存在时不会抛出错误,但InvalidOperation如果您尝试在$null对象上执行方法,则绝对会出错。并且严格模式完全抛弃了我的大部分点访问示例,因为当您尝试点访问空值对象上的任何成员时(以及其他额外的防护措施),严格模式会引发错误。

所以简而言之,如果你有带有方法的对象或者你在严格模式下运行 PowerShell,?.and运算符非常有用。?[]否则,在任何一种情况下,您都需要编写更多样板代码来首先进行空值检查。

于 2021-04-01T21:38:23.383 回答