我似乎经常发现自己处于一种情况,我设置了一堆变量,并且我想将它们传递给一个函数(例如,将参数传递给另一个函数而不进行修改)。目前我最终做了这样的事情:
Get-RelatedThing -CompanyTag $CompanyTag -ProjectTag $ProjectTag -EnvName $EnvName
这看起来很冗长,而且不易读取。我可以使用位置参数,但这会牺牲清晰度和兼容性。预先创建一个数组并使用splatting只会产生垂直杂波而不是水平(除非在不寻常的情况下,我可以做一些像Get-RelatedThing @PSBoundParameters,但这有陷阱)。
我真正喜欢的是能够做到这样的事情:
Get-RelatedThing @(Get-Variable CompanyTag,ProjectTag,EnvName)
但是Get-Variable返回一个Object [],而splatting运算符只能解析一个名为params(或一个位置参数数组)的哈希表。我stole是解决这个问题的函数:
function Get-VariablesAsHashtable {
[CmdletBinding()]
param
(
[Parameter(Position=0)]
[string[]] $Name
)
$ObjectArray = Get-Variable -Name @($Name)
$Hashtable = @{}
$ObjectArray | Foreach { $Hashtable[$_.Name] = $_.Value }
return $Hashtable
}
在“提前”运行时有效:
# works
$calculatedVars = (Get-VariablesAsHashtable ProjectTag,EnvName,ComponentTag);
(Get-RelatedThing @calculatedVars);
但不是在“内联”运行时:
# fails
(Get-RelatedThing @(Get-VariablesAsHashtable ProjectTag,EnvName,ComponentTag));
Get-InitialThing : Cannot process argument transformation on parameter 'ProjectTag'. Cannot convert value to type System.String.
我是否遗漏了可以修复此方法的内容?或者有更好的方法吗?
答案 0 :(得分:1)
看看这是否有效:
Get-RelatedThing @($(Get-Variable CompanyTag,ProjectTag,EnvName))
你可以用不同的功能实际上简化一些。这显示了splatting哈希表的效果:
$Params = @{
CompanyTag = 'Company1'
ProjectTag = 'Project1'
EnvName = 'Env1'
}
[Scriptblock]::Create("$(&{$args}@Params)")
-EnvName: Env1 -CompanyTag: Company1 -ProjectTag: Project1
修改原始功能以重现:
function Get-VariablesAsParameters {
[CmdletBinding()]
param
(
[Parameter(Position=0)]
[string[]] $Name
)
$ObjectArray = Get-Variable -Name @($Name)
[string]($ObjectArray | Foreach { '-{0}: {1}' -f $_.Name,$_.Value})
}
function Get-RelatedThing {$args}
Get-RelatedThing $(Get-VariablesAsParameters CompanyTag,ProjectTag,EnvName)
-CompanyTag: Company1 -ProjectTag: Project1 -EnvName: Env1
答案 1 :(得分:1)
实际上,你认为splatting只适用于hashtables是错误的。它也适用于数组,但它使用数组的每个元素作为被调用命令的位置参数。如果您确定所有值都在那里,那么您可以简单地绘制数组:
function Test-Binding {
param (
$Foo,
$Bar
)
"Foo: $Foo"
"Bar: $Bar"
}
$Foo = 'first value'
$Bar = 'other value'
$Splat = @(Get-Variable -ValueOnly Foo, Bar)
Test-Binding @Splat
你尝试过的内联语法失败的原因非常简单:在这种情况下,你不会出现问题。你在这一行中真正做了什么:
(Get-RelatedThing @(Get-VariablesAsHashtable ProjectTag,EnvName,ComponentTag));
...正在传递单个参数,你强制成一个数组(在这种情况下是@()
代表什么),单个哈希表的数组(你的函数产生的数组)。没有办法splat hashtable你正在构建“ad hoc”。您需要先构建它,存储在变量x中,然后使用@x
文字而不是通常的$x
将此变量作为“splat”传递。
我听说过填补这个空白的建议(语法如:command @@{ foo = 'bar'}
)但是在此之前,您必须先构建哈希表/数组,然后使用变量名称和@
进行展开前缀。