如果你想把一个函数的名称作为字符串传递: 使用&
运算符来调用它:
function A {
Param($functionToCall)
Write-Host "I'm calling: $(& $functionToCall)"
}
Function C {
"Function C"
}
A -functionToCall C
需要在"..."
内使用$(...)
的原因请参见这个答案,其中解释了PowerShell的字符串展开(字符串插值)规则。
上述代码生成I'm calling: Function C
请注意,函数C
使用隐式输出 (与显式使用Write-Output
相同) 来返回一个值。
Write-Host
通常是不正确的工具,除非明确要将内容写入显示器,而绕过PowerShell的输出流。
以下是通常需要使用&
运算符的情况:
脚本块是在PowerShell中传递代码段的首选方式;上述内容可以重新编写为 (请注意,调用机制不会改变,只是传递的参数改变):
function A {
Param($scriptBlockToCall)
Write-Host "I'm calling: $(& $scriptBlockToCall)"
}
Function C {
"Function C"
}
A -scriptBlockToCall { C }
在任何一种情况下,要传递参数,只需将它们放在& <commandNameOrScriptBlock>
之后;请注意如何使用splatting (@<var>
) 传递存储在自动变量 $args
中的未绑定参数。
function A {
Param($commandNameOrScriptBlockToCall)
Write-Host "I'm calling: $(& $commandNameOrScriptBlockToCall @Args)"
}
Function C {
"Function C with args: $Args"
}
A -commandNameOrScriptBlockToCall C one two
A -commandNameOrScriptBlockToCall { C @Args } one two
以上代码将两次输出 I'm calling: Function C with args: one two
。
注:
正如JohnLBevan所指出的,自动变量$args
仅在简单(非高级)脚本和函数中可用。
在param(...)
块上方使用[CmdletBinding()]
属性和/或每个参数上的[Parameter()]
属性会使脚本或函数成为一个高级脚本或函数,高级脚本和函数仅接受绑定到显式声明参数的参数。
如果您需要使用高级脚本或功能 - 例如支持带有[CmdletBinding(SupportsShouldProcess)]
的what-if功能 - 则通过以下方式传递参数:
如果仅需要通过位置(未命名)参数进行传递,则声明一个参数,例如[Parameter(ValueFromRemainingArguments)] $PassThruArgs
,它隐式收集传递的所有位置参数。
否则,必须显式声明所有潜在的(命名)传递参数的参数。
- 您可以使用PowerShell SDK基于现有命令构建参数声明,这是创建代理(包装器)函数的技术,如此答案所示。
或者,您的函数可以声明接受表示命名传递参数的哈希表的单个参数,以与splatting一起使用;当然,这需要调用方显式构造这样的哈希表。