[英](Not 1) evaluates to -2 for some reason
1
不是True
的整數表示, -1
是。
Debug.Print CInt(True) 'prints -1
Debug.Print CInt(False) 'prints 0
布爾運算符( Not
, And
, Or
, XOr
)在其操作數為布爾值時表現為“邏輯運算符”。 當他們不是,他們表現為“按位運算符”但事實是,他們總是按位。
整數值1
轉換為布爾值True
因為True
定義為Not False
,這意味着任何非零值都是布爾值True
。 但是,當您使用-1
表示True
時,您只能獲得正確/預期的邏輯行為。
Integer
由16位表示,因此1
是這樣的:
0000 0000 0000 0001
這使得Not 1
:
1111 1111 1111 1110
符號位打開,因此值為負 - 修剪無關緊要的數字,您得到:
10
這是2
的二進制表示。 因此, Not 1
是-2
。
相反, -1
將是:
1111 1111 1111 1111
因此Not -1
:
0000 0000 0000 0000
VBA / VBScript沒有真正的邏輯運算符(AND,OR,NOT)。 您看到的邏輯運算符實際上是按位運算符,而這就是您所獲得的。 VBA使用True
和False
值玩一些游戲,所以這大部分時間都有效,但偶爾你會找到一個“陷阱”。
在這種情況下,而不是If Not InStr() Then
你必須寫If InStr() <= 0 Then
。
而不是If InStr() Then
你必須寫If InStr() > 0 Then
換句話說: InStr()
返回一個數字 。 不要試圖像布爾一樣對待它。
由於其他答案已經解釋了為什么 ,我想專注於編碼實踐。
正如您所發現的, Not x
不一定是您想要的。 在實踐中,你想要更像Not CBool(x)
。 但是, CBool()
可能會拋出錯誤 - 例如, CBool(Null)
產生錯誤91(無效使用null)。
可能會聲稱您可以通過對變量進行強類型來避免這種情況,但即使不使用Variant
也不能保證在表達式中Boolean
將保持為Boolean
。 例:
?typename(true and 0)
Integer
在實踐中,很容易讓VBA意外地讓你為你做隱伏的轉換,所以出於這個原因,改變編碼習慣可能會更適合你。
要測試truthy值,您需要以下表達式:
If x Then
對於虛假值,您需要以下表達式:
If x = False Then
這些工作無論x
的類型如何,無論是否是表達式,因此與If x = True Then
或If Not x Then
相比,它的行為被認為更加一致/可預測。 通過采用這種代碼習慣,您可以幫助避免因意外轉換而產生的細微錯誤遠離Boolean
類型並獲得按位操作而不是邏輯操作。
對於賦值,使用Boolean
變量將確保它始終強制為True
或False
而不是一些隨機數。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.