在VBS中,我与SecureCRT一起使用以自动化思科设备上的某些进程,我(非常关注)以下代码:
Sub prConnectToHost(strConnectHost)
'If no host is passed into subroutine then we need to prompt for one.
If strConnectHost = "" Then strConnectHost = LCase(crt.Dialog.Prompt("Enter hostname or IP address:", "Connect to a host", strHost, False))
strHost = strConnectHost
'If user hits Cancel or hits Ok with no hostname entered then exit.
If strHost = "" Then
booReconnect = False
Exit Sub
End If
'Write to connection log
Call prWriteToConnectionLog
'Run command capture subroutine.
Call prCommandLoop
Set intWaitString = Nothing: Set strScreenGet = Nothing
Set strLatestScriptVersion = Nothing: Set strConnectHost = Nothing
End Sub
Sub Main有一个这样的部分:
Do While booReconnect = True
Call prConnectToHost("")
Loop
crt.Dialog.Prompt
与MsgBox
相同,只是它以窗口而不是屏幕为中心,因此它更整洁。变量strHost
是实际的主机名字符串,它在脚本中是全局的,包含我们要连接的主机名。它在Prompt
行中用作默认文本,其想法是,如果您断开连接并设置了booReconnect
标记,则会再次调用此Sub
,并在下次启用时提示输入旧的主机名 - 如果您第一次拼写错误,或者连接到一堆名称相似的设备,则会很有用。
您可以在prCommandLoop
的末尾看到我们拨打Sub
的位置,这是一个使用名为crt Function
的{{1}}的循环,该脚本暂停它找到一个特定的字符串序列。当它发生时,它会触发一些东西,然后循环回来,直到它再次等待。
其中一个自动化命令检测是否存在连接菜单(因此我们已退出路由器会话)并提示用户输入另一个主机名。
重要的一点是最后的变量clearup - WaitForStrings
。如果我将其保留并立即退出设置Set strConnectHost = Nothing
的{{1}},则只要prCommandLoop
被应用,booReconnect
就会死亡 - 如果我尝试引用它,则会收到错误{ {1}}。我尝试在Set strConnectHost = Nothing
的末尾添加strHost
行,证明了这一点。
奇怪的是,如果我先在Object Variable not set
中选择一个不同的自动化命令然后退出会话,MsgBox strHost
似乎不会打扰任何人。
任何人都可以帮我解释为什么这是一个问题,因为它令我感到困惑。我可以轻松解决这个问题(不在Sub
Sub的末尾发布prCommandLoop
),但我只想了解问题所在。
答案 0 :(得分:0)
设置用于将对象分配给变量。把Nothing想象成一个非常特殊的对象
>> WScript.Echo IsObject(Nothing)
>>
-1
仅用于指示变量的空虚。您的
Set strConnectHost = Nothing
将此Nothing分配给strConnectHost。在那之后,变量什么都不做 - 它保存了无法打印或用于计算或被要求做方法的空对象。
类型前缀欺诈(* str * ConnectHost)应该提醒您这很可疑。你使用字符串(和数字?);清除/重置它们使用(简单)赋值为Empty:
>> strConnectHost = Empty
>>
>> WScript.Echo IsEmpty(strConnection)
>>
-1
或具有合适的值:
intWaitString = -1 ' or 0 ...
(假设intWaitString不是另一种类型前缀欺诈)。
第二次尝试:
我假设你像这样打电话给你的潜水员:
strHost = "SomeHost"
prConnectToHost strHost
您子的相关摘要是:
Sub prConnectToHost( [ByRef] strConnectHost)
...
Set strConnectHost = Nothing
End Sub
由于VBScript使用引用传递参数作为默认值,因此您的修改 更改调用者变量strHost。这也发生在非对象变量上:
Dim sVar : sVar = "String 0"
WScript.Echo 0, sVar
changeString sVar
WScript.Echo 1, sVar
Sub changeString( sByRefVar )
sByRefVar = "String 1: changed by changeString( ByRef sByRefVar )"
End Sub
输出:
0 String 0
1 String 1: changed by changeString( ByRef sVar )
在您的情况下,修改将Nothing分配给被调用的变量 str中的strConnectHost和调用者级别的strHost。正如我之前所说, 这使得变量无用(除了测试Is Nothing之外)。
我希望这能解释strHost的崩溃。
WRT'内存管理':除了非常特殊的情况,你不需要 VBScript中的clear / reset / SetToNothing变量。在你的中使用局部变量 子/功能就是必要的。如果您决定使用全局变量 并且自己管理他们的状态,你必须注意变量类型: 从对象更改类型(包括Nothing)< =>非对象和撒谎 关于误导类型前缀的类型是危险的/可靠的方法。 如果您认为必须清除strHost,请将“空”或“”分配给strConnectHost。
下一次添加
所有VBScript变量都是变体,但并非所有变体都是相同的:
>> s0 = "string"
>> s1 = CStr( 12.35 )
>> WScript.Echo TypeName( s0 ), TypeName( s1 )
>>
String String
>> n0 = 1
>> n1 = CByte( n0 )
>> WScript.Echo TypeName( n0 ), TypeName( n1 )
>>
Integer Byte
TypeName()和VarType()显示子类型,progammer可以使用一组
C[hange/onvertTo]<Type>()
用于强制执行它们 - 在某种程度上,作为任务
可能会改变“引擎盖下的类型”。
>> WScript.Echo TypeName( n0 ), TypeName( n1 )
>>
Integer Byte
>> n0 = 1.1
>> n1 = 2 ^ 20
>> WScript.Echo TypeName( n0 ), TypeName( n1 )
>>
Double Double
甚至出现类型不匹配错误:
>> WScript.Echo Nothing
>>
Error Number: 13
Error Description: Type mismatch
>>
>> WScript.Echo s0 Is Nothing
>>
Error Number: 424
Error Description: Object required
所以子类型很重要。有些人认为类型前缀不合适,但其他人看到 它们在弱类型语言中作为有价值的帮助。如果您决定使用它们,那么 应该正确使用它们 -
Set strWhatEver = objWhatever
objWhatever = intWhatever
intWhatever = objWhatever
If strWhatEver = intWhatever Then
所有气味(没有注意类型,很难在以后的代码中确定错误)。