Recursion 递归调用函数,无需附加参数
我编写了vbscript函数,用于搜索Unix上的可用端口列表。因此,我的代码如下所示:Recursion 递归调用函数,无需附加参数,recursion,vbscript,Recursion,Vbscript,我编写了vbscript函数,用于搜索Unix上的可用端口列表。因此,我的代码如下所示: Function FindFreePorts(ByVal intPortToStart, ByVal intCountOfPortToSearch, ByVal arrFreePorts) Dim i, arrCommand, arrTmp, blnFindAllPort, j, strCommand Dim blnFree, intCountOfFreePorts strCommand
Function FindFreePorts(ByVal intPortToStart, ByVal intCountOfPortToSearch, ByVal arrFreePorts)
Dim i, arrCommand, arrTmp, blnFindAllPort, j, strCommand
Dim blnFree, intCountOfFreePorts
strCommand = "lsof -i | awk '{print $8}' | sed -n '/"
For i = intPortToStart To intPortToStart+intCountOfPortToSearch - 1
If i = intPortToStart+intCountOfPortToSearch - 1 Then
strCommand = strCommand & ".*"& i & "$/s/.*://p'"
Else
strCommand = strCommand & ".*:" & i &"\|"
End If
Next
Push arrCommand, strCommand
arrTmp = Array()
arrTmp = ExecuteCommandOnUnix(arrCommand, Null, _
Environment.Value("UNIXHOST_NAME"), _
Environment.Value("UNIXHOST_USER"), _
Environment.Value("UNIXHOST_PWD"))
' Count of busy port is UBound(arrTmp) - the other ports are free
' Find free ports
intCountOfFreePorts = intCountOfPortToSearch
For i = intPortToStart To intPortToStart+intCountOfPortToSearch - 1
blnFree = True
For j = 0 To UBound(arrTmp)
If arrTmp(j) = CStr(i) Then
blnFree = False
j = UBound(arrTmp)
End If
Next
If blnFree Then
Push arrFreePorts, i
intCountOfFreePorts = intCountOfFreePorts - 1
End If
Next
'
If intCountOfFreePorts = 0 Then
blnFindAllPort = True
Else
blnFindAllPort = False
End If
If Not blnFindAllPort Then
' We found UBound(arrFreePorts), we need to find intCountOfPortToSearch - UBound(arrFreePorts)
Do While intCountOfPortToSearch - UBound(arrFreePorts) - 1 <> 0
arrFreePorts = FindFreePorts(intPortToStart + intCountOfPortToSearch + 1, intCountOfPortToSearch - UBound(arrFreePorts) - 1, arrFreePorts)
If intCountOfPortToSearch - UBound(arrFreePorts) - 1 = 0 Then
Exit Do
End If
Loop
End If
FindFreePorts = arrFreePorts
End Function
但是我不知道如何在没有这个参数的情况下重写这个函数。然后我可以用更简单的方式来称呼它:
arrPort = FindFreePorts(intStartFromPort, intCountToSearch)
谢谢。
为了保持事物(实验,说明“邦德的贡献”)简单,让我们考虑把字符串的字符放进数组中的任务。
返回数组(不通过参数或全局获取)的函数需要创建数组:Function f1(s) ' default ByRef is ok, because Left and Mid return new (sub)strings
If "" = s Then
f1 = Array() ' return empty array for empty string
Else
Dim t : t = f1(Mid(s, 2)) ' recurse for tail - sorry no tail recursion
f1 = cons(Left(s, 1), t) ' copy! result of cons to f1/function's return value
End If
End Function
阵列的增长可以内联完成,但为了清晰起见,我使用了一个辅助函数:
调用函数很好:
WScript.Echo 3, "[" & Join(f1("12456789"), ",") & "]"
避免传递“The”数组的代价:
Function f2(s)
ReDim aTmp(-1)
s1 s, aTmp
f2 = aTmp
End Function
如果我正确地读取了代码,那么看起来每次函数调用都会传递数组的副本。由于您使用的是递归,因此可能会有很多副本!为什么不在调用作用域(最初调用
findfreeport
的作用域)中声明一个数组,并通过引用将该数组传递给findfreeport
。现在,您只需传递对数组的引用,而不是每次传递数组的副本。而且您不必返回它,这样您的函数
就可以成为子函数
。不过,您仍然需要您的推送
例程来动态增长阵列。谢谢,照您说的做了,一切正常,但速度更快:)谢谢,请澄清:)
WScript.Echo 3, "[" & Join(f1("12456789"), ",") & "]"
Sub s1(s, a) ' default ByRef is ok; a should be modified, s isn't touched
If "" <> s Then
ReDim Preserve a(UBound(a) + 1) ' grow! a
a(UBound(a)) = Left(s, 1)
s1 Mid(s, 2), a ' tail recursion for tail
End If
End Sub
ReDim a(-1) : s1 "123456789", a : WScript.Echo 3, "[" & Join(a, ",") & "]"
Function f2(s)
ReDim aTmp(-1)
s1 s, aTmp
f2 = aTmp
End Function