上一篇文章我們了解到了如何在 AHK 中比較字符串,但有一個細節我故意忽略了,也就是如何判斷一個字符串是否為空(或者說一個變量是否為空,AHK 中空變量、空字符串和未定義變量是一回事)。按理說這應該是一個很簡單的問題,一筆帶過即可,無需單獨寫一篇文章來介紹。對其他語言也許是這樣,但 AHK 在這個問題上存在一些麻煩,值得一提。
常規的字符串判空
a := ""
; 方法一:
; = 也可替換成 ==,因為空字符串無大小寫問題,不贅述
if (a = "")
{
; 條件成立
}
; 方法二:
if (a)
{
; 做正常的事情
}
else
{
; 條件成立
}
方法一就是其他編程語言中的方法,無需過多解釋。方法二是一種簡化的寫法,在多數情況看起來也是正常的,但存在一些特殊情況。
特殊情況一:數字 0
在一些特殊情況,方法二存在問題。
如果變量為字符串 "0",或者整數 0,或者浮點數 0.0:
a := "0"
; 或者
; a := 0
; 或者
; a := 0.0
; 方法一:
; = 也可替換成 ==,因為空字符串無大小寫問題,不贅述
if (a = "")
{
; 條件不成立
}
; 方法二:
if (a)
{
; 做正常的事情
}
else
{
; 條件成立,判斷錯誤
}
恐怕沒有人認為一個長度為一的字符串 "0" 是空字符串。但第二種方法給出了錯誤的結果。原因是 0 被認為是布爾值 false,而且 AHK 中的字符串和數字并沒有那么確切的區別,很多情況可以自動相互轉換,直接用 if 判斷自然不通過,看來這個簡化還是要不得。
特殊情況二:Object()
還有一種特殊情況是空對象 Object()。通常來說,我們不應該認為 Object() 是空變量,但某些庫的作者可能不嚴謹,在本應返回空變量的地方返回了 Object()(我印象中遇到過這樣的問題,但今天沒有復現出來,如果以后發現了再舉例)。如果用方法一判斷,就可能出問題。
a := Object()
; 方法一
; = 也可替換成 ==,因為空字符串無大小寫問題,不贅述
if (a = "")
{
; 條件不成立
}
; 方法三
if (StrLen(a) = 0)
{
; 條件成立
}
方法一認為 Object() 不是空變量,那么繼續將 a 傳遞下去處理,就可能出問題。方法三是調用 StrLen() 函數來檢查字符串的長度,它成功發現了這不是一個有效的字符串。
但用 StrLen() 函數判斷也存在問題,一個很嚴重的問題是方法三的耗時要比方法一長一倍以上。因為調用函數需要一些額外開銷,在幾乎所有語言都是如此。如果這個判斷在一個很大的循環里邊,額外的開銷是很大的。
另外 Object() 是否算空變量或者空字符串,這其實是有爭議的。我個人是認為不應該算,但在某些語言中,所有變量類型都是從 Object 類型繼承來的,那么就應該算。在用一些庫時,還是需要驗證一下是否存在 Object() 的問題,以免以后出了問題沒有頭緒。
總結
通常情況,用方法一判斷空字符串或者空變量就足夠了,簡單易懂。在某些特殊情況,可能需要用方法三來判斷,但要付出額外的開銷。另外本文可能還有一些細節沒有提到,我想起來后再補充。
付費解決 Windows、Linux、Shell、C、C++、AHK、Python、JavaScript、Lua 等領域相關問題,靈活定價,歡迎咨詢,微信 ly50247。