函数中不使用参数的默认值 [英] Default value of parameter is not used in function

查看:61
本文介绍了函数中不使用参数的默认值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个非常基本的 PowerShell 脚本:

I have a very basic PowerShell script:

Param(
    [string]$MyWord
)

function myfunc([string] $MyWord) {
    Write-Host "$MyWord"
}
myfunc @PSBoundParameters

这是我执行它的方式:

PS C:\> .\test.ps1 -MyWord 'hello'
hello

一切正常.但如果 -MyWord 未指定,我想设置一个默认值.我试过这个:

All fine. But I want to set a default value if -MyWord isn't specified. I tried this:

Param(
    [string]$MyWord='hi'
)

function myfunc([string] $MyWord) {
    Write-Host "$MyWord"
}
myfunc @PSBoundParameters 

但是我的脚本的输出只是空的.当我没有描述我的参数时,它什么也没打印.(如果我指定了参数,它只显示'hello').我也试过:

But than the output of my script was just empty. It was printing nothing when I did not describe my parameter. (it only showed 'hello' if I specified the parameter). I also tried:

Param(
    [string]$MyWord
)

function myfunc([string] $MyWord) {
    [string]$MyWord='hi'
    Write-Host "$MyWord" 
}
myfunc @PSBoundParameters

但输出当然总是嗨"而不是你好".即使我使用参数 -MyWord 'hello'

But than the output was of course always 'hi' and never 'hello'. Even when I executed the script with the parameter -MyWord 'hello'

有人可以解释我做错了什么吗?

Can someone explaining what I'm doing wrong?

当我不使用该功能时,它按预期工作:

When I'm not using the function it is working as expected:

Param(
    [string]$MyWord='hi'
)
Write-Host $MyWord

输出:

PS C:\> .\test.ps1 -MyWord 'hallo'
hallo

PS C:\> .\test.ps1
hi

推荐答案

自动变量$PSBoundParameters,顾名思义,只包含绑定 参数,其中 bound 表示实际值由调用者提供.

Automatic variable $PSBoundParameters, as the name suggests, contains only bound parameters, where bound means that an actual value was supplied by the caller.

因此,参数默认值限定为绑定关联参数,所以$MyWord 及其默认值 'hi' 不会成为 $PSBoundParameters 的一部分.

Therefore, a parameter default value does not qualify as binding the associated parameter, so $MyWord with its default value of 'hi' does not become part of $PSBoundParameters.

注意:可以说,具有默认值的参数也应该被视为绑定(它受其默认值约束,而不是受调用者提供的值约束).无论哪种方式,拥有一个也包含默认值的自动变量会很方便,以便能够简单而全面地传递参数.建议已提交到 PowerShell GitHub 存储库此处.

Note: Arguably, a parameter with a default value should also be considered bound (it is bound by its default value, as opposed to by a caller-supplied value). Either way, it would be convenient to have an automatic variable that includes default values too, so as to enable simple and comprehensive passing through of arguments. A suggestion has been submitted to the PowerShell GitHub repository here.

  • 以下解决方案假设您希望通过传递默认值,并且不想简单地复制函数 myfunc 中的默认值(如 Ansgar Wiecher 的有用答案 中所示),因为这会创建一个维护负担.

  • The following solutions assume that you want to pass the default value through, and don't want to simply duplicate the default value in function myfunc (as demonstrated in Ansgar Wiecher's helpful answer), because that creates a maintenance burden.

关于函数语法:以下两种形式等价,但出于一致性和可读性的考虑,您可能更喜欢后者.

Regarding function syntax: The following two forms are equivalent, though you may prefer the latter for consistency and readability.

  • function myfunc([string] $MyWord = 'hi') { ... }
    (...) 函数名后的参数声明.
  • function myfunc { param([string] $MyWord = 'hi') ... }
    param(...) 块内的参数声明在函数体内.
  • function myfunc([string] $MyWord = 'hi') { ... }
    parameter declaration inside (...) after the function name.
  • function myfunc { param([string] $MyWord = 'hi') ... }
    parameter declaration inside a param(...) block inside the function body.

一个简单的修复是将默认值显式添加到$PSBoundParameters:

A simple fix would be to add the default value explicitly to $PSBoundParameters:

Param(
     [string]$MyWord = 'hi'
)

function myfunc ([string] $MyWord){
    Write-Host "$MyWord" 
}

# Add the $MyWord default value to PSBoundParameters.
# If $MyWord was actually bound, this is effectively a no-op.
$PSBoundParameters.MyWord = $MyWord

myfunc @PSBoundParameters

<小时>

为了实现你想要的一般你必须使用反射(内省):


To achieve what you want generically, you must use reflection (introspection):

Param(
     [alias('foop')]
     [string]$MyWord = 'hi'
)

function myfunc ([string] $MyWord){
    Write-Host "$MyWord" 
}

# Add all unbound parameters that have default values.
$boundAndDefaultValueParams = $PSBoundParameters
foreach($paramName in $MyInvocation.MyCommand.Parameters.Keys) {
  if (-not $boundAndDefaultValueParams.ContainsKey($paramName)) {
    $val = Get-Variable $paramName -ValueOnly
    if ($null -ne $val) { $boundAndDefaultValueParams.Add($paramName, $val) }
  }
}

myfunc @boundAndDefaultValueParams

这篇关于函数中不使用参数的默认值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆