当使用$ null splat参数时,Powershell何时会使用默认值?

时间:2015-03-16 22:19:45

标签: powershell parameters null default scriptblock

考虑以下功能:

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会使用哪些类型来表示默认值?

4 个答案:

答案 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 参数,以便尊重被调用者的默认参数值。