我的功能如下:
function GeneratePermutations() {
Param(
[System.Collections.ArrayList]$Lists,
[ref][System.Collections.ArrayList]$result,
[Int]$depth,
[String]$current
)
if ($depth -eq $Lists.Count)
{
$result.Value.Add($current);
}
else
{
for ($i = 0; $i -lt $Lists[$depth].Count; $i = $i + 1)
{
GeneratePermutations $values $result ($depth + 1) ($current + $Lists[$depth][$i])
# tried as well:
# GeneratePermutations $values [ref]($result.Value) ($depth + 1) ($current + $Lists[$depth][$i])
}
}
}
我尝试使用它如下:
$x = New-Object System.Collections.ArrayList
GeneratePermutations $values [ref]($x) 0 ""
我得到以下异常(德语):
System.Management.Automation.ParameterBindingArgumentTransformationException: Die
Argumenttransformation für den Parameter "result" kann nicht verarbeitet werden. Der Wert "[ref]" vom Typ
"System.String" kann nicht in den Typ "System.Collections.ArrayList" konvertiert werden. --->
System.Management.Automation.ArgumentTransformationMetadataException: Der Wert "[ref]" vom Typ "System.String" kann
nicht in den Typ "System.Collections.ArrayList" konvertiert werden. --->
System.Management.Automation.PSInvalidCastException: Der Wert "[ref]" vom Typ "System.String" kann nicht in den Typ
"System.Collections.ArrayList" konvertiert werden.
bei System.Management.Automation.LanguagePrimitives.ThrowInvalidCastException(Object valueToConvert, Type
resultType)
bei System.Management.Automation.LanguagePrimitives.ConvertNoConversion(Object valueToConvert, Type resultType,
Boolean recurse, PSObject originalValueToConvert, IFormatProvider formatProvider, TypeTable backupTable)
bei System.Management.Automation.LanguagePrimitives.ConversionData`1.Invoke(Object valueToConvert, Type resultType,
Boolean recurse, PSObject originalValueToConvert, IFormatProvider formatProvider, TypeTable backupTable)
bei System.Management.Automation.LanguagePrimitives.ConvertTo(Object valueToConvert, Type resultType, Boolean
recursion, IFormatProvider formatProvider, TypeTable backupTypeTable)
bei System.Management.Automation.ArgumentTypeConverterAttribute.Transform(EngineIntrinsics engineIntrinsics, Object
inputData, Boolean bindingParameters, Boolean bindingScriptCmdlet)
--- Ende der internen Ausnahmestapelüberwachung ---
bei System.Management.Automation.ArgumentTypeConverterAttribute.Transform(EngineIntrinsics engineIntrinsics, Object
inputData, Boolean bindingParameters, Boolean bindingScriptCmdlet)
bei System.Management.Automation.ParameterBinderBase.BindParameter(CommandParameterInternal parameter,
CompiledCommandParameter parameterMetadata, ParameterBindingFlags flags)
--- Ende der internen Ausnahmestapelüberwachung ---
bei System.Management.Automation.ExceptionHandlingOps.CheckActionPreference(FunctionContext funcContext, Exception
exception)
bei System.Management.Automation.Interpreter.ActionCallInstruction`2.Run(InterpretedFrame frame)
bei System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
bei System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
In Zeile:1 Zeichen:1
+ .\process.ps1
+ ~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException
+ FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,process.ps1
我认为我有一个递归重用结果数组的问题,有人能告诉我如何解决这个问题吗?似乎powershell想要将结果数组转换为它显然无法做到的字符串,但为什么它会尝试将其转换为字符串?
答案 0 :(得分:1)
我在递归函数中通过引用传递参数时遇到了同样的问题,并得出结论,在PowerShell中设置[Ref]类型并不会增加很多值,如果你将它与例如它进行比较。 VBScript ByRef
参数。
我找到了解决这个问题的方法:
将您的变量放在HashTable(或PSCustomObject)中,@{Var = $Result}
哪些属性将通过引用。在你的情况下,我可能只是使用HashTable而不是数组:
function GeneratePermutations() {
Param(
[System.Collections.ArrayList]$Lists,
[HashTable]$result = @{},
[Int]$depth,
[String]$current
)
if ($depth -eq $Lists.Count)
{
$result.$current = $True;
}
else
{
for ($i = 0; $i -lt $Lists[$depth].Count; $i = $i + 1)
{
GeneratePermutations $values $result ($depth + 1) ($current + $Lists[$depth][$i])
}
}
}
或者从参数集中删除相关的$Result
变量并创建一个变量,该变量的写作范围来自递归函数的根(并且不会覆盖可能已存在的$Result
变量:
If (@(Get-PSCallStack)[1].Command -ne $MyInvocation.MyCommand.Name) {
New-Variable -Name Result -Option AllScope -Value @()
}
if ($depth -eq $Lists.Count)
{
$result.Add($current);
...
答案 1 :(得分:0)
以下语法有效:
bin/setup
认为游戏中有一些运算符优先级,见下文。
GeneratePermutations $values ([ref]$x) 0 ""
在第一个实例中,我们得到了引用的文本表示,它的[PS]> [ref]$x
Value
-----
{, , , ...}
[PS]> [ref]$x.gettype()
Value
-----
System.Collections.ArrayList
[PS]> ([ref]$x).gettype()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
False False PSReference`1 System.Management.Automation.PSReference
属性是对象。
在第二个中,我们看到我们仍然得到一个引用,但现在Value
是Value
,它实际上是一个字符串。可能是当在函数之间传递时,正在处理类型时会有一些反射,或者某些东西正在调用System.Collections.ArrayList
,并且函数以此字符串引用结束,导致您看到的错误。
在第三个示例中,您可以看到已经返回了正确的类型,并且当像这样传递给您的函数时,错误消失并且一切都按预期运行。