如果你真的想将函数的名称作为字符串传递:使用&,调用运算符,调用它:
function A {
Param($functionToCall)
# Note the need to enclose a command embedded in a string in $(...)
Write-Host "I'm calling: $(& $functionToCall)"
}
Function C {
"Function C" # Note: Do NOT use Write-Host to output *data*.
}
A -functionToCall C
至于"..."里面需要使用$(...):见this answer,里面解释了PowerShell的字符串扩展(string-interpolation)规则。
以上产生I'm calling: Function C
注意函数C 如何使用隐式 输出(与显式使用Write-Output 相同)返回值。
Write-Host is generally the wrong tool to use,除非意图明确写入显示器仅,绕过 PowerShell 的输出流。
您一般在以下场景中需要& 运算符:
Script blocks 是在 PowerShell 中传递代码片段的首选方式;上面可以重写为(注意调用机制不会改变,只是传递的参数):
function A {
Param($scriptBlockToCall)
Write-Host "I'm calling: $(& $scriptBlockToCall)"
}
Function C {
"Function C" # Note: Do NOT use Write-Host to output *data*.
}
A -scriptBlockToCall { C }
在任何一种情况下,要传递参数,只需将它们放在:& <commandNameOrScriptBlock> 之后即可;注意splatting (@<var>) 是如何用于传递存储在automatic $args variable 中的未绑定参数的。
function A {
Param($commandNameOrScriptBlockToCall)
Write-Host "I'm calling: $(& $commandNameOrScriptBlockToCall @Args)"
}
Function C {
"Function C with args: $Args"
}
A -commandNameOrScriptBlockToCall C one two # by name
A -commandNameOrScriptBlockToCall { C @Args } one two # by script block
以上产生I'm calling: Function C with args: one two 两次。
注意:
-
正如JohnLBevan 指出的那样,自动$args 变量仅在简单(非高级)脚本和函数中可用。
-
在param(...) 块上方使用[CmdletBinding()] 属性和/或每个参数的[Parameter()] 属性使脚本或函数成为advanced 之一,并且高级脚本和函数还只接受参数绑定到显式声明的参数。
-
如果您需要使用高级脚本或函数 - 例如通过 [CmdletBinding(SupportsShouldProcess)] 支持假设功能 - 您有以下选择来传递参数:
-
如果传递位置(未命名)参数就足够了,请声明一个参数,例如[Parameter(ValueFromRemainingArguments)] $PassThruArgs,它会隐式收集调用时传递的所有位置参数。
-
否则,您必须为所有潜在的(命名的)传递参数显式声明参数。
- 您可以借助 PowerShell SDK(一种用于创建代理(包装)函数的技术)基于现有命令构建参数声明,如 this answer 所示。
-
或者,您的函数可以声明一个接受 hashtable 的参数,该参数代表命名的传递参数,用于 splatting;当然,这需要调用者显式构造这样的哈希表。