Show/Hide Toolbars

XSharp

用途

声明并初始化局部变量和数组。

语法

[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

 

参见