Autohotkey 中文论坛

完整版: 如何让函数调用全局变量?
你目前正在浏览的是简化版. 请点击这里浏览完整版
如果我自己建一个函数如下:
add(c,d)
{
return a+b+c+d ;a和b都是全局变量,即函数括号以外的变量
}


如果单单这么写的话add会return一个空值
所以现在请教一下,如何在自建函数里调用外部全局变量?前提是不要增加参数(即函数开头括号里的变量,不知道这个“参数”表述对不对)。

谢谢!

。。最近在尝试编一个自动扫雷的脚本。。把写好的sub改成自建函数后,才发现无法调用函数以外的变量






解决方法:
用global来声明变量是全局的,引用一下中文帮助文档里的内容:

全局变量
要在一个函数里引用一个存在的全局变量(或创建一个新的),需要在使用它之前先声明此变量为 global。例如:

LogToFile(TextToLog){ global LogFileName ;这个全局变量先前已经在此函数外赋过值了。 FileAppend, %TextToLog%`n, %LogFileName%}如果一个函数需要引用或创建大量的全局变量,可以通过将它的首行设为单词"global"或者声明一个局部变量来假设它所有的变量都是全局的(它的参数除外)。例如:

SetDefaults(){ global ;如果在此函数的首行有比如"local MyVar"这样的词,那么这个单词可以被省略。 Var := 33 ;将 33 赋值给一个全局变量,如果需要,首次可创建变量。 local x, y:=0, z ;局部变量必须用这种形式来声明,不然它们会被假定为全局变量。 ; ...等等。}这种假设的全局模式也可以被函数用来创建一个全局数组,例如一个赋值给 Array%A_Index% 的循环。

静态变量
一个变量可以被声明为 static 来使它的值在多次调用期间被记住。例如:

LogToFile(TextToLog){ static LineCount = 0 LineCount += 1 ;保持自身的累加(它的值在多次调用期间能被记住)。 global LogFileName FileAppend, %LineCount%: %TextToLog%`n, %LogFileName%}静态变量一般都是隐式的局部变量。在 1.0.46 之前的版本,所有的静态变量都以空值开始;所以要检查一个静态变量首次被使用的唯一办法就是检查它是否为空值。在 v1.0.46 及之后的版本,一个静态变量可以初始化为除了 "" 外的东西,通过其后跟 := 或 = 以及下列之一:true, false, 一个原义的整数,一个原义的浮点数,或一个引用的/原义的字符串比如 "fox"。例如: static X:=0, Y:="fox"。每个静态变量都只初始化一次(在脚本执行之前)。

关于局部和全局的更多信息:
在下面例子中,通过逗号将多种变量分隔开从而在同一行声明:

global LogFileName, MaxRetries := 5static TotalAttempts = 0, PrevResult在 v1.0.46 及之后版本,一个局部或者全局变量可以在同一行被初始化,通过在它的声明后加上 := 或 = 以及任何表达式(在声明中运算符 = 和 := 作用相同)。在一个特定行有多个声明时,由于性能原因(不像普通的逗号分隔语句)每个有初始化设定的声明都被作为单独的行执行。与静态变量初始化设定不同,局部变量和全局​变量的初始化设定在每次函数被调用时都会执行,但是仅当控制流实际能到达它们这时。换句话说,在一行中写下 local x = 0 和在两个单独的行写下 local x 以及 x = 0 的作用是一样的。

因为单词 local, global 和 static 在脚本启动时会被立即处理,所以不能用 IF 语句来有条件地声明变量。换句话说,在一个 IF 或 ELSE 区块里的声明,声明与函数末尾大括号之间的所有行都会无条件地生效。同时注意目前还不可能声明一个动态变量比如 global Array%i%。

在一个函数里,任何动态变量引用比如 Array%i% 常常会解析为一个局部变量,除非那个名称的变量不存在,在这时才会使用全局变量如果它存在的话。如果两者都不存在,那么需要变量先被创建才能使用,它会被创建为一个局部变​量,除非假设全局模式已生效。因此,仅当函数被定义为假设全局函数时,它才能够手动地创建一个全局数组(比如使用 Array%i% := A_Index 这样的方法)。

对于创建数组的命令(例如 StringSplit),如果假设全局模式未生效或者数组的首个元素已声明为局部变量(将函数的一个参数传递给它也可以 -- 即使那个参数是 ByRef 的 -- 因为参数和局部变量很相似),那么得出的数组就是局部的。相反的,如果首个元素已被声明为全局,那么创建的是全局数组。StringSplit 的首个元素是 ArrayName0。对于其他创建数组的命令比如 WinGet List,首个元素是 ArrayName(即没有数字)。

常见疑点:在脚本启动时对变量的任何非动态引用都将创建那个变量。例如:在脚本启动的时候,在函数外使用 MsgBox %Array1% 将创建全局的 Array1。相反的,在脚本启动时,在函数内部使用 MsgBox %Array1% 将创建 Array1 作为函数局部变量之一(除非假设全局已生效)。
add(c,d)
{
f:=a+b+c+d
return f ;a和b都是全局变量,即函数括号以外的变量
}
引用:原帖由 aqtd 于 2008-12-31 16:46 发表 [Image: back.gif]
add(c,d)
{
f:=a+b+c+d
return f  ;a和b都是全局变量,即函数括号以外的变量
}

该方法似乎无效,刚查了一下中文帮助,里面提到要用global这个命令来声明。。现在正在看到底杂用。。
a=3
b=4
f:=add(5,6)
MsgBox,%f%
add(c,d)

{
global a,b
return a+b+c+d ;a和b都是全局变量,即函数括号以外的变量
}


[ 本帖最后由 aqtd 于 2008-12-31 18:22 编辑 ]
全局数组的定义格式是怎么写?
global Last%aaa%
这样写不行呀
writing GLOBAL in the first line of the function, which makes all variables in the function to be global.
参考网址