声明并初始化局部变量和数组。
[STATIC] LOCAL <idVar> [:= <uValue>] [,...] [AS | IS <idType>] [, ...]
[STATIC] LOCAL DIM <ArraySpec> [, ...] AS | IS <idType> [, ...]
[STATIC] LOCAL <ArraySpec> [, ...] [AS ARRAY] [, ...]
LOCAL ARRAY <arrayName> ( <nRows> [, <nColumns>] ) [, <arrayName> ( <nRows> [, <nColumns>] ) ] // 仅用于 FoxPro 方言
LOCAL ARRAY <arrayName> [ <nRows> [, <nColumns>] ] [, <arrayName> [ <nRows> [, <nColumns>] ] ] // 仅用于 FoxPro 方言
注:为方便起见,LOCAL 语句使用了多个语法。 如果每个定义之间用逗号隔开,则可以使用一条 LOCAL 语句声明变量、动态数组和维数组。
STATIC | 使局部变量在调用声明实体时保留其值,但不影响其可见性。 |
<idVar> | 要声明的局部变量的有效标识符名称。 |
<uValue> | 分配给变量的初始值。 |
当使用 LOCAL 时,这可以是任何有效的表达式。 |
当使用 STATIC LOCAL 时, 该值可以是下列数据类型的字面表示,也可以是只涉及运算符、字面表示和 DEFINE 常量的简单表达式;但不允许使用更复杂的表达式(包括类实例化)。 |
注意:虽然 <uValue> 可以是字面数组,但必须是一维数组。 不允许使用多维字面数组。 例如,{1, 2, 3} 是允许的,但 {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}} 则不允许。 |
注意:虽然 Chr() 函数不能在 <uValue> 中使用,但 _Chr() 操作符可以。 _Chr() 在其他方面的功能与 Chr() 完全相同。 |
如果未指定 <uValue>,变量的初始值取决于所声明的数据类型(例如,如果不使用强类型,则为 NIL;如果使用 AS INT,则为 0,等等)。 |
DIM <ArraySpec> | 要声明的有维数的数组。 |
<ArraySpec> | 要声明的动态数组。 在这两种情况下,<ArraySpec> 都是以下其中之一: |
<idArray>[<nElements>, <nElements>, <nElements>]
<idArray>[<nElements>][<nElements>][<nElements>]
除了第一个维度外,所有维度都是可选的。
<idArray> 要声明的数组的有效标识符名称。对于动态数组,数组元素初始化为 NIL。对于定维数组,元素的初始值取决于数据类型,如上文对 `<uValue>` 的解释。 |
<nElements> 定义数组特定维度中的元素数量。维度由你指定的 <nElements> 参数的数量决定。 |
<nElements> 可以是一个字面数字表示,或者是仅涉及运算符、字面量和 DEFINE 常量的简单数字表达式;然而,不允许使用更复杂的表达式(例如函数调用)。 |
AS <idType> | 指定数据类型。如果省略,编译器依据编译选项来决定数据类型,或者是 USUAL,或者是由编译器自行决定。 |
IS <idType> | 指定一种结构体数据类型,在这种数据类型中,结构体所需的内存将在堆栈中分配(<idStructure> 是唯一允许使用 IS 关键字的 <idType> 类型)。有关数据结构体内存分配的更多信息,请参阅本指南中的 VOSTRUCT 。 |
AS ARRAY | 对于动态数组声明,指定整个数组的数据类型。 |
<arrayName> | 数组的变量名。数组的大小与 <nRows> 和 <nColumns> 所声明的一样。数组可以使用括号作为分隔符,也可以使用方括号。 |
我们建议使用方括号。 |
LOCAL 是一种声明语句,用于将一个或多个变量或数组声明为当前例程(即函数、方法或存储过程)的局部变量或数组。 与其他变量声明语句(如 FIELD 和 MEMVAR)一样,必须将 LOCAL 语句放在定义例程中的任何可执行语句(包括 PRIVATE、PUBLIC 和 PARAMETERS)之前。
局部变量声明会隐藏所有继承的私有变量、可见的公有变量、实例变量、全局变量和同名常量。 变量名的搜索顺序如下:
1. LOCAL、局部参数、MEMVAR 和 FIELD
2. SELF 实例变量(即在类方法中不带 <idObject>: 前缀)
3. GLOBALs 和 DEFINEs
如果 LOCAL 语句声明的变量名已在同一例程中声明(使用 FIELD、LOCAL 或 MEMVAR),则编译器会出错。
局部变量只在当前例程中可见,与私有变量不同,在被调用的例程中不可见。 如果例程被递归调用,每次递归激活都会创建一组新的局部变量。
除非指定 STATIC 关键字,否则每次开始执行声明局部变量的例程时,都会自动创建局部变量。 它们将继续存在并保留其值,直到声明例程将控制权返回给调用它的例程。
STATIC 关键字可作为局部变量的生命周期修改器,防止变量在创建实体返回调用例程时从内存中释放。
这一点很重要! 当调用包含静态变量声明的应用程序时,变量将在程序开始执行前创建并初始化。 因此,初始值只在每次程序运行时分配一次,而不是在每次调用创建实体时分配。
局部参数: 通过 FUNCTION、METHOD 和 PROCEDURE 语句,可以在实体名称后面的括号中声明局部参数列表。 例如
FUNCTION <idFunction>(<idParamList>)
通过代码块导出局部变量: 创建代码块时,可以在代码块定义中访问创建实体中定义的局部变量,而无需将其作为参数传递(因为局部变量对代码块是可见的)。 再加上可以将代码块作为参数传递,因此可以导出局部变量。 例如
FUNCTION One()
LOCAL nVar := 10 AS INT, cbAdd AS CODEBLOCK
cbAdd := {|nValue| nValue + nVar}
? NextFunc(cbAdd) // 结果: 210
FUNCTION NextFunc(cbAddEmUp)
RETURN EVAL(cbAddEmUp, 200)
当在 NextFunc() 中对代码块进行求值时,函数 One() 的局部参数 nVar 将变得可见,即使它没有直接作为参数传递。
宏表达式: 不能在宏变量和表达式中引用局部变量。 如果在宏变量中引用局部变量,将引用同名的私有变量或公有变量。 如果不存在此类变量,则会出现运行时错误。
局部变量的类型: 由于 Type() 使用宏运算符 (&) 来评估其参数,因此不能用它来确定局部变量或包含局部变量引用的表达式的类型。 不过,您可以使用 ValType() 评估参数并返回返回值的类型。
内存文件: 不能保存或恢复局部变量。
下面的示例声明了两个局部数组和两个局部变量:
LOCAL aArray1[20, 10], aArray2[20][10], var1, var2
本例声明了两个带有初始化器的局部变量。 第一个变量初始化为一个日期值,第二个变量初始化为一个数组:
LOCAL dWhen := TODAY()
LOCAL aVegies := {"Tomato", "Chickadee", "Butterbean"}
在本例中,变量 x 和维数数组 z 的类型为 INT,而变量 cName 和 cAddr 的类型为 STRING:
LOCAL x, DIM z[100] AS INT, cName, cAddr AS STRING
下一个示例声明了带初始化器和不带初始化器的静态变量:
STATIC LOCAL aArray1[20, 10], aArray2[20][10]
STATIC LOCAL cVar, cVar2
STATIC LOCAL cString := "my string", var
STATIC LOCAL aArray := {1, 2, 3}
这里,静态变量在函数中被操作。 在本例中,每次调用函数时,计数变量都会自增:
FUNCTION MyCounter(nNewValue)
// 分配一次初始值
STATIC LOCAL nCounter := 0
IF nNewValue != NIL
// nCounter 的新值
nCounter := nNewValue
ELSE
// 递增 nCounter
++nCounter
ENDIF
RETURN nCounter
FIELD, FUNCTION, DEFINE, GLOBAL, MEMVAR, METHOD, PROCEDURE, STATIC, DIMENSION, DECLARE, PUBLIC