AHK 中有两种比较像的东西,标签和函数。

标签

标签比较简单,用来标记一段代码的位置,以 return 结束。

Gosub, Test
Goto, Test
; 不再执行
MsgBox, End

Test:
    MsgBox, Test
return

Test 就是一个标签。标签可以用 Gosub 调用,Gosub 执行完后会继续执行下一行。也可以用 Goto 调用,但 Goto 调用完就不会回来了。

除了使用 Gosub 或者 Goto 调用,标签还可以作为其他命令的参数,比如 Hotkey、SetTimer 等等。

标签里的代码默认是执行的。比如这样一个 AHK 文件。

MsgBox, Begin

Test:
    MsgBox, Test
return

即使没有主动调用 Test 标签,Test 标签里的内容还是会被执行。

可以使用动态的标签名来调用标签。

labelName := "Test"

; IsLabel 函数用来判断标签是否存在
if (IsLabel(labelName))
{
    Gosub, %labelName%
}

函数

函数也可以实现标签的功能,但更强大和灵活。

Test1()
Test2("test")

Test1()
{
    MsgBox, Test1
}

; 函数支持参数和返回值
Test2(text)
{
    MsgBox, % text
    return true
}

函数的调用方式是函数名加小括号,如果需要传递参数,在括号里添加参数。和标签不一样,函数里的代码默认是不执行的。

可以使用动态的标签名来调用函数。

functionName := "Test"

; IsFunc 函数用来判断函数是否存在
if (IsFunc(functionName))
{
    %functionName%()
}

函数里可以调用标签,标签里也可以调用函数。标签和函数可以重名。

函数里的标签

在函数里可以再定义标签。

Test()
{
    Gosub, Test2
    return

    Test2:
        MsgBox, Test2
    return
}

代码中 Test2 是一个内部标签,只能在 Test 函数中访问。但不同函数中的内部标签也不能够重名,即所有的标签名必须是唯一的。

标签和函数的区别

总结下标签和函数的区别:

  1. 定义和调用的方式不同。
  2. 函数支持参数和返回值,标签不支持。
  3. 标签默认是执行的,函数默认不执行。
  4. 调用标签的开销比调用函数小,调用空函数的耗时比调用空标签多百分之几十。
  5. 函数中可以使用局部变量和静态变量,但标签中只能使用全局变量。
  6. 某些场景可能只允许用标签,但最新的 AHK 版本基本所有场景都可以用函数了(如果以后想起来有不可取代的场景再补充)。

那么是使用标签还是函数呢?

通常情况,使用函数就可以了。如果考虑到性能,在无需参数和返回值的情况可以用标签取代函数。除非一个函数被高频率地调用,否则优化的效果不大。