从示例开始
有人提问(加不加括号,效果截然不同 • AHKScript),在帮助文档 ListView 的一个示例中(注:这里只是片段,完整代码请参阅帮助 ListView 页面):
Code: Select all
GuiContextMenu:
if A_GuiControl <> MyListView
return
Menu, MyContextMenu, Show, %A_GuiX%, %A_GuiY%
return
Code: Select all
GuiContextMenu:
if (A_GuiControl <> MyListView)
return
Menu, MyContextMenu, Show, %A_GuiX%, %A_GuiY%
return
为什么会这样呢?因为他在不理解 If 传统型和 If(表达式)就加上括号,这是产生问题的根源,加上括号则成了表达式(在修改后的脚本中),同时 MyListView 成了变量,但该脚本中不存在这个变量,实际上换成任何一个脚本中不存在的变量名效果都一样(不过这里的名称有迷惑性,让人误解它有特定意义)。为什么还能运行?这必须提到 AutoHotkey 的变量机制:使用即存在,换句话说,大部分情况下当我们需要变量时直接使用就行了。如果是其他语言,一般会出现变量不存在的提示。
从另一角度看,困惑的来源是为什么会存在容易引起误解的两种风格呢?AutoHotkey 最初参照自典型命令式语言 AutoIt v2,这是传统型存在的历史原因,因为有些情况下传统型无法解决,在开发过程中加强了表达式型,所以目前形成并存的局面。
传统赋值与表达式赋值
Code: Select all
str = 这是个字符串。 ; 传统赋值
str := "这是个字符串。" ; 表达式赋值
Code: Select all
str = 这是个字符串,后面跟着 Var 变量的内容:%var%
str := "这是个字符串,后面跟着 Var 变量的内容:" var
Code: Select all
var = 1 + 1
var := 1 + 1
如果能明确它们的区别,可以两者都用。如果担心会混淆,那么只能采用表达式赋值了,这是我对初学者建议的方法。
If 传统型与 If 表达式型
这里包含好几个命令及等价的比较结构,除了 If 表达式型外我唯一建议使用的是下面这种形式:
Code: Select all
If var
MsgBox, var 变量既不为零也不为空。
IfEqual, var, value (等同于: if var = value)
IfNotEqual, var, value (等同于: if var <> value) (可以使用 != 代替 <>)
IfGreater, var, value (等同于: if var > value)
IfGreaterOrEqual, var, value (等同于: if var >= value)
IfLess, var, value (等同于: if var < value)
IfLessOrEqual, var, value (等同于: if var <= value)
这些命令都很简单,名称的含义也显而易见。第一个变量是不需要百分号括住的变量,第二个是原义的值。可以使用两种形式:
IfNotEqual, var, value (等同于: if var <> value) (可以使用 != 代替 <>)
IfGreater, var, value (等同于: if var > value)
IfGreaterOrEqual, var, value (等同于: if var >= value)
IfLess, var, value (等同于: if var < value)
IfLessOrEqual, var, value (等同于: if var <= value)
Code: Select all
IfEqual, var, value
MsgBox, 变量 var 的值为:value。
if var = value
MsgBox, 变量 var 的值为:value。
Code: Select all
if (var = "value")
MsgBox, 变量 var 的值为:value。
Code: Select all
if (Mod(intYear, 100) ? Mod(intYear, 400) : Mod(intYear, 4))
MsgBox, % intYear "不是润年。"
两种同时使用不行吗?
在只赋值字符串时使用传统形式,而需要运算时则通过表达式,两者都很简单,为什么非要两者选一呢?这样的问题不是“行不行”,既然语言自身提供了,当然不会不行。主要问题在于如果没有理解,那么会给您带来困惑,即让您的脚本增加出错的可能。
请看这个例子:
Code: Select all
if Var = ""
MsgBox, 变量 Var 为空。
您刚才是否在想当 Var 变量为空时这个 If 语句结果为真呢?这样就错了,实际是只有在 Var 包含一对双引号时才为真。如果要判断一个变量是否为空,正确的传统形式和表达式形式应该这样:
Code: Select all
; 传统形式
if Var =
MsgBox, 变量 Var 为空。
; 表达式形式
if (Var = "")
MsgBox, 变量 Var 为空。
小结
最后,从 AutoHotkey Basic 到 AutoHotkey_L 中表达式型一直在加强,个人猜测 AutoHotkey v2 版本可能完全转向表达式型(目前测试版中尚未实现,但在 Thoughts for v2.0 中 Lexikos 有这种倾向),所以不论从目前的理解或以后的学习、过渡而言,建议采用表达式型。