programing

매개변수로서의 기능 전달

linuxpc 2023. 9. 13. 22:21
반응형

매개변수로서의 기능 전달

저는 여러 다른 함수 중 하나를 호출하는 함수 'A'를 작성했습니다.다시 쓰기 함수 'A'를 저장하기 위해 함수 'A'의 파라미터로 호출되는 함수를 전달하고자 합니다.예를 들어,

function A{
    Param($functionToCall)
    Write-Host "I'm calling : $functionToCall"
}

function B{
    Write-Host "Function B"
}

Function C{
    write-host "Function C"
}

A -functionToCall C

반환:전화합니다: C

저는 그것이 돌아올 것으로 기대하고 있습니다.전화 드립니다.함수 C.

저는 다음과 같은 다양한 시도를 해보았습니다.

Param([scriptblock]$functionToCall)

시스템을 변환할 수 없습니다.문자열과 스크립트 블록 연결

A -functionToCall $function:C

"Write-Host "Function C"를 반환합니다.

A - functionToCall (&C)

나머지 부분에 대해서는 다음과 같이 평가합니다.

 Function C
 I'm Calling :

이것이 101번 프로그래밍이라고 확신하지만 정확한 구문이나 잘못하고 있는 것이 무엇인지 이해할 수 없습니다.

이게 최선인지는 모르겠지만,

function A{
    Param([scriptblock]$FunctionToCall)
    Write-Host "I'm calling $($FunctionToCall.Invoke(4))"
}

function B($x){
    Write-Output "Function B with $x"
}

Function C{
    Param($x)
    Write-Output "Function C with $x"
}

PS C:\WINDOWS\system32> A -FunctionToCall $function:B
I'm calling Function B with 4

PS C:\WINDOWS\system32> A -FunctionToCall $function:C
I'm calling Function C with 4

PS C:\WINDOWS\system32> A -FunctionToCall { Param($x) "Got $x" }
I'm calling Got x

ScriptBlock을 매개 변수로 전달하는 것에 대해 생각해 보셨습니까?

$scriptBlock = { Write-Host "This is a script block" }
Function f([ScriptBlock]$s) {
  Write-Host "Invoking ScriptBlock: "
  $s.Invoke()
}

PS C:\> f $scriptBlock
Invoking ScriptBlock:
This is a script block

함수의 이름을 문자열전달하려면 , 호출 연산자를 사용하여 호출합니다.

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

할 에 는 는 에를 사용할 에 대해서는$(...)에서 안에"...": PowerShell의 문자열 확장(string-interpolation) 규칙을 설명하는 이 답변을 참조하십시오.

의 결과는 의 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"  # Note: Do NOT use Write-Host to output *data*.
}

A -scriptBlockToCall { C }

두 시나리오 중 하나에서 인수를 전달하려면 다음 다음 다음에 배치하기만 하면 됩니다.& <commandNameOrScriptBlock>; at는 방법을 기록합니다(@<var>)는 자동 변수에 저장된 결합되지 않은 인수를 전달하는 데 사용됩니다.

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두번이라.

참고:

  • 존 L 베번이 지적한 것처럼, 자동은$argsvariable은 단순(고급이 아닌) 스크립트 및 함수에서만 사용할 수 있습니다.

  • .[CmdletBinding()] 위의 param(...) 및록는수[Parameter()]attribute는 스크립트나 함수를 고급 스크립트나 함수로 만들고 고급 스크립트나 함수는 추가로 명시적으로 선언된 매개 변수에 바인딩되는 인수만 허용합니다.

  • What-if 기능을 지원하는 등 고급 스크립트나 기능을 사용해야 하는 경우[CmdletBinding(SupportsShouldProcess)]- 인수를 통과하기 위해 다음과 같은 선택사항이 있습니다.

    • 위치(이름 없는) 인수를 전달하기에 충분하다면 다음과 같은 매개 변수를 선언합니다.[Parameter(ValueFromRemainingArguments)] $PassThruArgs, 호출 시 전달되는 모든 위치 인수를 암묵적으로 수집합니다.

    • 그렇지 않으면 모든 잠재적(이름이 지정된) 패스스루 인수에 대한 매개 변수를 명시적으로 선언해야 합니다.

      • 이 답변과 같이 프록시(wrapper) 기능을 만드는 데 사용되는 기술인 PowerShell SDK를 사용하여 기존 명령을 기반으로 파라미터 선언을 스캐폴드할 수 있습니다.
    • 또는 이름이 지정된 통과 인수를 나타내는 해시 테이블을 허용하는 단일 매개 변수를 선언하여 분할에 사용할 수 있습니다. 물론 호출자가 이러한 해시 테이블을 명시적으로 구성해야 합니다.

이게 필요하신 건가요?

function A{
    Param($functionToCall)
    Write-Host "I'm calling : $functionToCall"

    #access the function-object like this.. Ex. get the value of the StartPosition property
    (Get-Item "function:$functionToCall").ScriptBlock.StartPosition

}

function B{
    Write-Host "Function B"
}

Function C{
    write-host "Function C"
}


PS> a -functionToCall c

I'm calling : c


Content     : Function C{
                  write-host "Function C"
              }
Type        : Position
Start       : 307
Length      : 43
StartLine   : 14
StartColumn : 1
EndLine     : 16
EndColumn   : 2

던컨의 해결책은 제게 아주 효과적이었습니다.그러나 함수 이름에 대시가 포함되어 있는 경우 문제가 발생합니다.

저는 그의 세 번째 사례를 바탕으로 이 문제를 해결할 수 있었습니다.

function A{
    Param([scriptblock]$functionToCall)
    Write-Host "I'm calling $($functionToCall.Invoke(4))"
}

function Execute-FunctionWithDash($x)
{
    Write-Output "Function Execute-FunctionWithDash with $x"
}

PS C:\WINDOWS\system32> A -functionToCall { Param($x) Execute-FunctionWithDash $x }
I'm calling Function Execute-FunctionWithDash with 4

지정된 모수의 변동 수를 전달하는 경우

function L($Lambda){
   write-host "`nI'm calling $Lambda"
   write-host "`nWith parameters"; ft -InputObject $Args
   & $Lambda @Args
}

이상한 함수 이름과 잘 어울리는 것 같습니다.

function +Strange-Name($NotUsed,$Named1,$Named2){
   ls -filter $Named1 -Attributes $Named2
}

PS C:\>L +Strange-Name -Named1 *.txt -Named2 Archive

그리고 exe 파일들도.

PS C:\>L grep.exe ".*some text.*" *.txt

아직 주사를 조심해야 할 것 같은데요

function inject($OrigFunction){
   write-host 'pre-run injection'
   & $OrigFunction @Args
   write-host 'post-run injection'
}

PS C:\>L inject +Strange-Name -Named1 *.txt -Named2 Archive
    function strdel($a,$b,$c) {
    return ($a.substring(0,$b)+$(substr $a $c $a.length))
}
function substr($a,$b,$c) {
    return $a.substring($b,($c-$b))
}

$string = "Bark in the woods"
$in = $(substr $(strdel $string 0 5) 0 2)
write-host $in

여기서 함수 'substr'은 함수 'strdel'을 $a 매개 변수로 불렀습니다.

https://github.com/brandoncomputer/vds 의 기능

다음은 어떻습니까?

function A{
Param($functionToCall)
    $res = Invoke-Command $functionToCall 
    Write-Host "I'm calling : $res"
}

function B{
    "Function B"
}

Function C{
    "Function C"
}

A -functionToCall ${function:C}

${function:...}을(를) 사용하여 함수를 값으로 전달합니다. 함수를 호출하고 결과를 $res에 저장합니다.

언급URL : https://stackoverflow.com/questions/22129621/pass-function-as-a-parameter

반응형