考虑以下VBS:
dim msg, myVar, myVar2
msg = "myVar = " & myVar
msg = msg & vbcrlf & "myVar = empty: " & isempty(myVar)
msg = msg & vbcrlf & "TypeName(myVar) = " & TypeName(myVar)
msgbox msg, , "BEFORE"
if not myVar then myVar2 = true
msg = "myVar = " & myVar
msg = msg & vbcrlf & "myVar = empty: " & isempty(myVar)
msg = msg & vbcrlf & "TypeName(myVar) = " & TypeName(myVar)
msgbox msg, , "AFTER"
我希望“BEFORE”和“AFTER”的输出相同......我们所做的只是对未初始化(空)变体进行比较吗?
然而 - 似乎“if not”实际上将它初始化为(长)零! 我一直在用VBS(ASP)为驴子编码,这对我来说是新的!
有几点需要注意:
对于粗心大意的人来说这似乎是一个潜在的陷阱......任何人都可以解释这种行为吗?
答案 0 :(得分:6)
我无法找到关于这个问题的任何官方消息。 做了一些测试后,我认为这是一个错误或未记录的效果。 此行为不适用于其他类似平台,如VBA和VB6。
Visual Basic for Application:
Visual Basic 6:
<强>的VBScript:强>
作为一种解决方法,按值传递表达式。
If Not (exp) Then
'or
If Not CBool(exp) Then
答案 1 :(得分:5)
如果您将中间的语句更改为
if not (myVar) then myVar2 = true 'with parenthesis around myVar
那么你将不会目睹同样的行为。之前和之后现在都是一样的。
那是因为显然括号强制Not运算符只执行逻辑测试,并且会跳过Not的副作用。
在https://msdn.microsoft.com/en-us/subscriptions/9cy86sfb%28v=vs.84%29.aspx上,您会找到以下关于不
的内容In addition, the Not operator inverts the bit values of any variable and
sets the corresponding bit in result according to the following table:
+-------------------+---------------+
| Bit in expression | Bit in result |
+-------------------+---------------+
| 0 | 1 |
| 1 | 0 |
+-------------------+---------------+
例如
Msgbox Not 2 ' is -3
Msgbox Not -3 ' is 2
如果您在内部将值存储为带符号的字节/单词,那么这是有意义的。
000 -4
001 -3 --> 001 inverted is 110
010 -2
011 -1
100 0
101 1
110 2 --> 110 inverted is 001
111 3
让我们用
将Empty转换为Longx = CLng(myVar)
你会发现x的值是0。
如果您使用
if not myVar then myVar2 = true
然后将评估不是myVar的结果(随后抛出结果值-1将被丢弃)。但无论如何都要进行计算,为此必须先将Empty转换为long。
答案 2 :(得分:4)
https://technet.microsoft.com/en-us/library/ee198865.aspx
因此,如果您在不初始化变量的情况下创建变量,则该变量将采用以下默认值之一: 如果将变量用作字符串,则初始值将为Empty。 如果将变量用作数字,则初始值将为0.
我认为既然你正在做布尔检查,你实际上是使用myVar作为数字,你的语句如下:
if not 0 then myVar2 = true
'same as: if not FALSE then myVar2 = true
所以myVar初始化为0
答案 3 :(得分:3)
这些是VBA https://msdn.microsoft.com/en-us/library/ee177324.aspx?f=255&MSPPError=-2147217396
的规则关键是变量(尽管不是对象)总是具有可用值(对象确实没有值)。
5.5.1.2.2允许强制转换为布尔
如果没有存储为布尔值,则False用0表示,True用非零值表示,通常为-1。
布尔Let-coercion的语义取决于源的值类型和目标的声明类型:
Source Value Type Destination Declared Type Semantics
Boolean Boolean The result is a copy of the source value.
Boolean Any numeric type except Byte If the source value is False, the result is 0. Otherwise, the result is -1.
Boolean Byte If the source value is False, the result is 0. Otherwise, the result is 255.
Any numeric type Boolean If the source value is 0, the result is False. Otherwise, the result is True
5.5.1.2.11从空的强制
Empty Let-coercion的语义取决于目标的声明类型:
Source Value Type Destination Declared Type Semantics
Empty Any numeric type The result is 0.
Empty Boolean The result is False.
Empty Date The result is 12/30/1899 00:00:00.
Empty String The result is a 0-length string.
Empty String * length The result is a string containing length spaces.
Empty Any class or Object Runtime error 424 (Object required) is raised.
Empty Any other type except Variant Runtime error 13 (Type mismatch) is raised.
当您第一次使用消息框时,您的变量将被强制为字符串。
然后它在上面被强制为假。
5.6.9.5关系运算符 关系运算符是简单的数据运算符,用于执行操作数之间的比较。
relational-operator = equality-operator / inequality-operator / less-than-operator / greaterthan-operator / less-than-equal-operator / greater-than-equal-operator
静态语义:
关系运算符作为简单数据运算符静态解析。
如果任何操作数的声明类型是数组或UDT,则关系运算符无效。
关系运算符具有以下声明的类型,基于其操作数的声明类型:
Left Operand Declared Type Right Operand Declared Type Operator Declared Type
Any type except an array, UDT or Variant Any type except an array, UDT or Variant Boolean Any type except an array or UDT Variant
Variant Any type except an array or UDT Variant
运行时语义:
首先将关系运算符评估为简单数据运算符。
如果任何操作数的值类型是数组或UDT,则会引发运行时错误13(类型不匹配)。
在评估关系运算符之前,它的非空操作数经过Let-coercion到运算符的有效值类型。
有效值类型根据操作数的值类型确定如下:
5.6.9.5.1 =运算符
=运算符对其操作数执行值相等性比较。 equality-operator = expression&#34; =&#34;表达
运行时语义:
如果认为操作数相等,则返回True。否则,返回False。