将函数及其参数作为函数的参数传递

时间:2019-08-07 09:06:56

标签: powershell functional-programming

我想编写一个接受一个函数及其参数的函数。

当我对它进行硬编码时,我可以在一个函数中运行一个函数,但这不是我所需要的。 Powershell支持一流的功能,因此应该可行。

这有效:

function pass_arg{
    param([string] $arg)
    Write-Host "pass_arg ran with: $arg"
}

function pass_runner{
    param([string] $arg)
    pass_arg $arg
}

pass_runner "some string argument."

这不是:

function func_w_arg{
    param([string] $arg)
    Write-Host "func_w_arg ran with: $arg"
}

function runner_w_func{
    param($func, [string] $arg)
    #Runner stuff...
    func $arg
}
runner_w_func func_w_arg "some string argument"

错误:

func : The term 'func' is not recognized as the name of a cmdlet, function, script file, or
operable program. Check the spelling of the name, or if a path was included, verify that the
path is correct and try again

因此,当我尝试使用

时,错误发生在流转函数的名称空间中
$func

可调用的参数。

1 个答案:

答案 0 :(得分:0)

两个选项:

  1. 将命令名称传递给呼叫运营商&,或
  2. 传递[scriptblock]作为参数化参数:

1。传递命令名称:

function func_w_arg{
    param([string] $arg)
    Write-Host "func_w_arg ran with: $arg"
}

function runner_w_func{
    param([string]$func, [string] $arg)
    #Runner stuff...
    & $func $arg
}

runner_w_func func_w_arg "some string argument"

2。传递[scriptblock]

function func_w_arg{
    param([string] $arg)
    Write-Host "func_w_arg ran with: $arg"
}

function runner_w_func{
    param([scriptblock]$func, [string] $arg)
    #Runner stuff...
    & $func $arg
}

runner_w_func func_w_arg "some string argument"

如您所见,调用运算符接受两者,因此我们不妨将它们组合在一起:

function Invoke-Function {
    param(
        [ValidateScript({$_ -is [string] -or $_ -is [scriptblock]})]
        [object]$func,
        [string] $arg
    )

    & $func $arg
}

处理参数

但是,如果您有多个参数怎么办?

通过接受参数列表数组或字典来解决此问题,您需要为内部函数命名参数绑定:

function Invoke-Function {
    param(
        [ValidateScript({$_ -is [string] -or $_ -is [scriptblock]})]
        [object]$func,
        [array]$ArgumentList,
        [System.Collections.IDictionary]$NamedArguments
    )

    if($PSBoundParameters.ContainsKey('ArgumentList')){
        return & $func $ArgumentList @NamedArguments
    }

    return & $func @NamedArguments
}