我编写了vbscript函数,用于搜索Unix上的空闲端口列表。所以我的代码看起来像这样:
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
如您所见,我在Do While
周期中递归调用此函数。一切正常,但我不喜欢这里的arrFreePorts参数。所以我应该编写这段代码来执行我的函数:
arrPort = FindFreePorts(intStartFromPort, intCountToSearch, arrPort)
但我不知道如何在没有此参数的情况下重写此函数。然后我可以用更简单的方式调用它:
arrPort = FindFreePorts(intStartFromPort, intCountToSearch)
提前致谢。
答案 0 :(得分:1)
为了保持事物(实验,@ Bond的贡献的说明)简单,让我们考虑将字符串的字符放入数组中的任务。
一个返回数组的函数(不通过参数或全局获取)需要创建数组:
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
数组的增长可以内联完成,但为了清楚起见,我使用辅助函数cons():
Function cons(e, a) ' default ByRef is ok; neither e nor a are changed
ReDim aTmp(UBound(a) + 1) ' create larger array
Dim i : i = 0
aTmp(i) = e ' 'new' head
For i = 1 To UBound(aTmp)
aTmp(i) = a(i - 1) ' copy 'old' elms
Next
cons = aTmp ' copy! aTmp to cons/function's return value
End Function
调用该函数很好:
WScript.Echo 3, "[" & Join(f1("12456789"), ",") & "]"
避免传递'the'数组的代价:
作为在这种情况下,递归调用可以/应该在'相同'数组上工作,Sub可以更有效地完成任务(并且不那么复杂):
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