考虑以下功能:
function f1{
param(
$sb = {},
$s = ''
)
if ($sb -isnot [scriptblock]) { 'scriptblock' }
if ($s -isnot [string] ) { 'string' }
}
现在使用splat参数调用它:
PS C:\> $splat = @{foo='bar'}
PS C:\> f1 @splat
正如所料,没有任何回报。现在使用$null
splat参数再次尝试:
PS C:\> $splat = $null
PS C:\> f1 @splat
scriptblock
奇怪的是,scriptblock
被退回。显然,至少对于[scriptblock]
参数,当使用$null
splat参数时,powershell不会遵循默认值。但是,powershell确实遵守了[string]
的默认值。这是怎么回事?
当使用$ null splat参数时,Powershell会使用哪些类型来表示默认值?
答案 0 :(得分:2)
这不仅仅是位置参数的正常应用吗?您正在展示正在应用于$null
的单个$sb
。
比较
> function f{ param($sb = {}, $s = '') $PSBoundParameters }
> $splat = @(1,2)
> f @splat
Key Value
--- -----
sb 1
s 2
> f @flkejlkfja
Key Value
--- -----
sb
> function f{ param($aaa = 5, $sb = {}, $s = '') $PSBoundParameters }
> f @splat
Key Value
--- -----
aaa 1
sb 2
答案 1 :(得分:2)
这是一个古老的问题,但如果它仍然有趣......
正如其他人使用$splat = $null
调用f1 @splat
编写的那样,第一个参数将获得值$null
,而不是默认值。
如果您希望参数在这种情况下使用其默认值,则必须使用$splat = @{}
或$splat = @()
。
答案 2 :(得分:1)
这是一个帮助了解正在发生的事情的演示
$splat = @{foo='bar'}
"$(&{$args}@splat)"
-foo: bar
当您展开哈希表时,它会转换为-Key:值字符串对,它们将成为您函数的参数。
现在尝试:
$splat = $null
"$(&{$args}@splat)"
没有返回任何内容。没有用于生成参数字符串的键,因此最终结果与根本不传递任何参数相同。
答案 3 :(得分:1)
通过更直接的演示补充Etan Reisner's helpful answer splatting $null
确实通过$null
作为第一个(且仅限)位置参数:
$splat = $null
& { [CmdletBinding(PositionalBinding=$False)] param($dummy) } @splat
以上产生以下错误:
A positional parameter cannot be found that accepts argument '$null'.
...
使用param()
修饰[CmdletBinding(PositionalBinding=$False)]
块可确保只传递命名的参数值,从而导致位置传递{{1}从splatting触发上面的错误。
请注意使用特殊的" null集合"从不产生splatting输出的命令中获得的值($null
)实际上与splatting [System.Management.Automation.Internal.AutomationNull]::Value
相同,因为" null collection"在参数绑定期间,值将转换为$null
。
VargaJoe's helpful answer解释了如何构造用于splatting的变量,以便传递 no 参数,以便尊重被调用者的默认参数值。