问题
为什么$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 + @{}))
为我们提供了一种完全安全的方法来添加哈希表,其中任一值都可以为null。 最佳答案
我试图找出原因,但我不能确定。
我最初的信念是:
"1"+1
时,右边的1变为字符串,输出为"11"
,但是右边的1+"1"
变为数字,输出为2
。$null + @{}
会抛出强制转换错误,或者强制转换并执行null + null = null,不会像那样输出空哈希表。 A.op_Addition(B)
之类的方法调用,并且它将向上左边的东西说当您尝试在右边添加东西时会发生什么。@{} + 0
告诉您哈希表只能添加到哈希表中。 (说谎,您可以将其添加为null)。 0 + @{}
告诉您哈希表不包含op_Addition
方法。因此,带有null的加法似乎应该给出该错误,但不会,因为它不会退回到这种机制。 PSv3语言规范(我认为这是可用的最新版本),请在此处下载:https://www.microsoft.com/en-us/download/details.aspx?id=36389,并提及以下内容:
通常的算术转换为:
这意味着在两个示例中,$ null都将转换为0。虽然这不可能发生,因为
0 + @{}
和@{} + 0
都是错误。在第7.7节中明确提到要添加两个哈希表:
好的,哈希表添加由PowerShell引擎处理,但仅添加两个哈希表。
第7章:引言
从我在规范中可以看到,PowerShell似乎未定义$ null + Hashtable操作,并且
+
的相应方法是op_Addition
-哈希表没有的方法,请参见前面的错误代码-这是不会抛出该错误,不仅是该错误,而且在加0的情况下,错误来自右操作数而不是左操作数。规范中另一个有趣的地方是:
因此,摘要似乎是:
@{} + $null
-触发PowerShell添加两个哈希表的处理,即使规范未说明会这样做。 $null + @{}
-似乎有一个隐式的$null + x = x
规则,尽管该规范似乎没有提及它,并且可能取决于实现。 [<type>]$null
-将$ null强制转换为数字类型会导致0(6.15算术转换),但是将其强制转换为其他任何值(?)似乎会导致$ null(在规范中未列出)。 $null
没有类型违反了PowerShell规范4.1.2“空类型”,其中说“空类型具有一个实例,自动变量$ null(§2.3.2.2),也称为空值。未指定此类型的特征。”因此,至少在术语上,即使您无法在PowerType上将它描述为一种类型,..