0

我有一个函数,它返回一个复杂的嵌套哈希表数据结构,其中一部分构成进一步函数调用的参数,一部分是用于报告导致参数未填充的错误的字符串。理想情况下,我想只使用参数哈希表,但我开始认为这是不可能的。因此,基本问题的示例如下所示...

function Test {
    param (
        [String]$A,
        [String]$B,
        [String]$C
    )
    Write-Host "A: $A"
    Write-Host "B: $B"
    Write-Host "C: $C"
}

$data = @{
    arguments = @{
        A = 'A string'
        B = 'Another string'
        C = 'The last string'
    }
    kruft = 'A string that doesn not need to get passed'
}

理想情况下,我想 splat $data.arguments,所以像这样...... Test @data.arguments 但这不起作用,导致错误

The splatting operator '@' cannot be used to reference variables in an expression. '@data' can be used only as an argument to a command. To 
reference variables in an expression use '$data'.

所以我尝试 Test @(data.arguments) 了...导致错误

data.arguments : The term 'data.arguments' 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.

我也试过...... Test @($data.arguments) 这导致整个哈希表作为单个参数传递,输出是

A: System.Collections.Hashtable
B: 
C:

起作用的是……

$arguments = $data.arguments
Test @arguments

这让我认为除了一个简单的变量(即适当的哈希表)之外,您真的不能吐出任何东西。但是,我希望有人可以验证这确实是真的,或者指出我还没有想出的解决方案。实际代码需要 5 个参数,名称有些冗长,因为我更喜欢描述性名称,因此喷溅是非常合适的解决方案。只需要使用要传递的哈希表来创建一个新变量不是问题,只是想知道它是否真的是唯一的选择。

4

2 回答 2

1

我不能声称完全理解您的尝试,但这里有一些可能会有所帮助的解决方案。

您的Test函数需要三个字符串,但我在您的示例中看不到任何满足此要求的内容。我要么将其更改为接受 a Hashtable(这是有问题的数据类型),要么让它接受一个字符串数组并通过$data.arguments.values

使用Hashtable

function Test {
  param (
    [Hashtable]$hash
  )

  write-host $hash.A
  write-host $hash.B
  write-host $hash.C
}

Test $data.arguments

使用String数组:

function Test {
  param (
    [String[]]$a
  )

  $a | % { write-host $_ }
}

Test $data.arguments.values
于 2020-09-11T12:27:07.990 回答
1

那是不可能的。

对于函数参数,使用“@”而不是“$”提供的任何变量(并且只有变量)都被声明为 TokenKind“SplattedVariable”。

请参阅: https ://docs.microsoft.com/en-us/dotnet/api/system.management.automation.language.tokenkind?view=powershellsdk-7.0.0

PS: 我这边的一些快速测试可能会成功(除了 PS 设计):

Write-Host 'Test 1' -ForegroundColor Yellow
Test @$data.arguments

Write-Host 'Test 2' -ForegroundColor Yellow
Test @$($bla = $data.arguments)

Write-Host 'Test 3' -ForegroundColor Yellow
Test @$bla = $data.arguments

Write-Host 'Test 4' -ForegroundColor Yellow
Test @$bla = $data.arguments.GetEnumerator()

Write-Host 'Test 5' -ForegroundColor Yellow
Test @$($data.arguments.GetEnumerator())

......但他们没有。

于 2020-09-11T13:44:44.770 回答