2

考虑以下函数:

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被退回。显然,至少对于参数,当使用splat 参数[scriptblock]时,powershell 不遵守默认值。$null但是 powershell 确实尊重[string]. 这里发生了什么?

使用 $null splat 参数时,Powershell 支持哪些类型的默认值?

4

4 回答 4

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
于 2015-03-16T22:50:04.803 回答
2

这是一个老问题,但如果它仍然很有趣......

$splat = $null正如其他人在调用f1 @splat第一个参数时所写的那样,将获得该值$null而不是默认值。

如果您希望参数在这种情况下使用它们的默认值,您必须使用$splat = @{}or $splat = @()

于 2018-04-21T18:25:21.877 回答
1

这是一个演示,可帮助您了解正在发生的事情

$splat = @{foo='bar'}
"$(&{$args}@splat)"
-foo: bar

当您 splat 哈希表时,它会转换为 -Key: Value 字符串对,这些字符串对成为您的函数的参数。

现在尝试:

$splat = $null
"$(&{$args}@splat)"

什么都没有返回。没有用于生成参数字符串的键,因此最终结果与根本不传递任何参数相同。

于 2015-03-17T02:23:41.393 回答
1

为了补充Etan Reisner 的有用答案,更直接地证明splatting$null确实$null作为第一个(也是唯一的)位置参数传递:

$splat = $null
& { [CmdletBinding(PositionalBinding=$False)] param($dummy) } @splat

以上产生以下错误

A positional parameter cannot be found that accepts argument '$null'.
...

用 with装饰param()[CmdletBinding(PositionalBinding=$False)]确保只能传递命名参数值,导致 from splatting 的位置传递$null触发上述错误。

请注意,使用[System.Management.Automation.Internal.AutomationNull]::Value从不产生喷溅输出的命令中获得的特殊“空集合”值 () 实际上与喷溅相同$null,因为该“空集合”值$null在参数绑定期间转换为。


VargaJoe 的有用答案解释了如何构造一个用于 splatting 的变量,以便不传递任何参数,从而尊重被调用者的默认参数值。

于 2018-05-05T02:22:46.660 回答