问题
为什么$null + @{}
有效,但@{} + $null
没有;即使将null转换为哈希表(@{} + ([hashtable]$null)
)。
示例代码
[hashtable]$a = @{demo1=1;demo2='two'}
[hashtable]$b = @{demo3=3;demo4='Ivy'}
[hashtable]$c = $null
#combining 2 hashtables creates 1 with both hashes properties (would error if any properties were common to both)
write-verbose 'a + b' -Verbose
($a + $b)
#combining a null hashtable with a non-null hashtable works
write-verbose 'c + a' -Verbose
($c + $a)
#combing 2 null hashtables is fine; even if we've not explicitly cast null as a hashtable
write-verbose 'c + null' -Verbose
($c + $null)
#however, combinging a hashtable with null (i.e. same as second test, only putting null as the right argument instead of the left, produces an error
write-verbose 'a + c' -Verbose
($a + $c)
输出
Name Value
---- -----
demo3 3
demo4 Ivy
demo1 1
demo2 two
VERBOSE: c + a
demo1 1
demo2 two
VERBOSE: c + d
VERBOSE: a + c
A hash table can only be added to another hash table.
At line:19 char:1
+ ($a + $c)
+ ~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : AddHashTableToNonHashTable
旁注
顺便说一下,这让我发现了这个哈希表的空合并操作的有用技巧:($c + @{})
。例如($a + ($c + @{}))
避免了上面产生的错误/ (($a + @{}) + ($c + @{}))
为我们提供了一种完全安全的方法来添加哈希表,其中任何一个值都可以为空。
答案 0 :(得分:2)
我试图找出原因,但我无法确定。
我最初的信念是:
"1"+1
,右侧的1变为字符串,输出为"11"
,但1+"1"
右侧变为数字,输出为2
。
$null + @{}
要么抛出一个强制转换错误,要么强制转换为null + null = null,而不是像它那样输出一个空的哈希表。A.op_Addition(B)
告诉您哈希表只能添加到哈希表中。 (谎言,你可以将它添加到null)。并且@{} + 0
告诉您哈希表不包含0 + @{}
方法。所以添加null似乎应该给出错误,但不会,因为它不会回到这个机制。PSv3语言规范(我认为是最新版本),请点击此处下载:https://www.microsoft.com/en-us/download/details.aspx?id=36389,提及补充:
7.7.1加法描述:加法运算符+的结果是平时后两个操作数指定的值的总和 已应用算术转换(第6.15节)。
通常的算术转换说:
如果两个操作数都没有指定具有数字类型的值,则[..]指定值$ null的所有操作数都将转换为int类型的零,并且该过程将继续下面列出的数字转换。
这意味着在您的示例中,$ null将转换为0。虽然这不可能发生,因为op_Addition
和0 + @{}
都是错误。
在第7.7节中明确提到添加两个哈希表:
7.7.4 Hashtable concatenation描述:当两个操作数指定Hashtables时,binary +运算符创建一个新的Hashtable 其中包含左操作数指定的元素 立即由右操作数指定的元素。
好的,散列表添加由PowerShell引擎处理,但只添加两个哈希表。
第7节介绍说:
Windows PowerShell:如果PowerShell未定义操作,则会检查左操作数指定的值的类型,以查看它是否具有相应的op_方法。
操作$ null + Hashtable似乎不是由我在规范中看到的PowerShell定义的,@{} + 0
的相应方法是+
- 一个哈希表做的方法没有,请参阅前面的错误代码 - 这不是抛出错误,不仅如此,但在添加到0的情况下,错误来自右操作数而不是左操作数。
规范中另一个有趣的地方是:
4.1.2未指定null类型的特征。
所以摘要似乎是:
op_Addition
- 触发PowerShell处理添加两个哈希表,即使规范没有说它会。@{} + $null
- 看起来有一个隐含的$null + @{}
规则,虽然规范似乎没有提到它,但它可能依赖于实现。$null + x = x
- 将$ null转换为数字类型会导致0(6.15算术转换),但将其转换为其他任何内容(?)似乎会导致$ null(不在规范中)。[<type>]$null
没有类型符合PowerShell规范4.1.2“null类型”,其中说“null类型有一个实例,自动变量$ null(§2.3。 2.2),也称为空值。这种类型的特征是未指定的。“所以至少在术语中,它被描述为PowerShell中的一种类型,即使你不能在其上使用GetType()..