转移控制权。
GOTO
间接符,和偏移量, mac可以。goto
只可以到例程标签名字GOTO:pc
GOTO:pc goargument,...
G:pc
G:pc goargument,...
其中,goargument是:
location:pc
GOTO
命令有两种形式:
GOTO
无参数不带参数的goto
在Caché在当前执行的代码中遇到错误或中断命令后恢复正常的程序执行。只能在终端提示符下使用无参数GOTO
。
下面的示例显示了无参数GOTO
的用法。在此示例中,由于
错误而未执行第二次写入;发出GOTO
命令将继续执行,执行第二次写入:
DHC-APP>WRITE "before" BREAK WRITE "after"
before
WRITE "before" BREAK WRITE "after"
^
<BREAK>
DHC-APP 1S0>goto
after
请注意,BREAK
命令后必须有两个空格。
如果在发出无参数GOTO
时NEW
命令生效,则Caché会发出
错误,并保留新上下文。使用Quit 1
命令,然后使用无参数GOTO
在新操作后继续。
也可以在终端提示符下使用无参数 GOTO
,以便在出错后继续执行。
GOTO
有参数带有参数location的goto将控制转移到指定位置。如果在命令或参数上指定后置条件表达式,则仅当后置条件表达式的计算结果为true(非零)时,Caché才会转移控制权。
可以从编程模式提示符使用转到位置在不同位置恢复中断的程序。
可以将$CASE
函数指定为GOTO
命令参数。
可使命令具有条件的可选后置条件表达式。如果后置条件表达式附加到GOTO
命令关键字后,如果后置条件表达式为TRUE(计算结果为非零数值),则Caché将执行GOTO
命令。如果后置条件表达式为假(计算结果为零),则Caché不执行GOTO
命令。如果后置条件表达式附加到参数后,如果后置条件表达式为TRUE(计算结果为非零数值),则Caché将执行该参数。如果后置条件表达式为假(计算结果为零),则Caché跳过该参数并计算下一个参数(如果有)或下一个命令。
控制权将转移到的点。它在例程代码中是必需的。在编程器模式提示符下是可选的。可以将位置指定为单个值或逗号分隔的值列表(带有后置条件),并且可以采用以下任何形式:
Label+Offset
指定当前例程内的行标签。可选的+offset
是一个非负整数,它指定开始执行的标签之后的行数。Offset
计算代码行(包括标签行),并计算注释行;Offset
不计算空行和注释内的空行。但是,OFFSET
确实计算所有嵌入的SQL行,包括所有空行。
label+offset^routine
在指定的例程中指定行标签,该例程驻留在磁盘上。Caché从磁盘加载例程,并在指定的标签处继续执行。可选的+offset
是一个非负整数,它指定开始执行的标签之后的行数。
^ROUTINE
指定驻留在磁盘上的例程。Caché从磁盘加载例程,并在例程内的第一行可执行代码处继续执行。如果例程已修改,则当GOTO
调用例程时,Caché加载例程的更新版本。与DO
命令不同,GOTO
在例程执行后不会返回到调用程序。如果指定的例程不存在,则Caché会发出
错误消息。
注意:GOTO
不支持扩展例程引用。要在另一个命名空间中执行例程,请使用do
命令。
还可以将LOCATION
作为包含上述任何表单的变量进行引用。不过,在这种情况下,必须使用名称间接。location 不能指定使用形参列表或用户定义的函数或过程的名称定义的子例程标签。如果指定的标签不存在,则Caché会发出
错误消息。
调用CACHESYS%
例程时不能指定偏移量。如果尝试这样做,Caché会发出
错误。
在下面的示例中,GOTO
根据用户提供的生存期值将执行定向到三个位置之一。位置是存储在变量loc
中的子例程标签,然后通过名称间接(@loc
)引用。
mainloop
SET age=""
READ !,"你几岁了? ",age QUIT:age=""
IF age<30 {
SET loc="Young"
}
ELSEIF (age>29)&(age<60) {
SET loc="Midage"
}
ELSEIF age>59 {
SET loc="Elder"
}
ELSE {
WRITE "data input error"
QUIT
}
GOTO @loc
QUIT
Young
WRITE !,"你还年轻"
QUIT
Midage
WRITE !,"你正处于巅峰时期"
QUIT
Elder
WRITE !,"你有一生的智慧可以传授"
QUIT
DHC-APP>d mainloop^PHA.TEST.Command
你几岁了? 50
你正处于巅峰时期
DHC-APP>d mainloop^PHA.TEST.Command
你几岁了? 2
你还年轻
DHC-APP>d mainloop^PHA.TEST.Command
你几岁了? 70
你有一生的智慧可以传授
请注意,在过程块中不允许使用名称间接的这种类型的GOTO
。
或者,可以省略if
命令,并在参数上使用后置条件用逗号分隔的列表编写goto
代码,如下所示:
GOTO Young:age<30,Midage:(age>29)&(age<60),Elder:age>59
mainloop
SET age=""
READ !,"你几岁了? ",age QUIT:age=""
IF age<30 {
SET loc="Young"
}
ELSEIF (age>29)&(age<60) {
SET loc="Midage"
}
ELSEIF age>59 {
SET loc="Elder"
}
ELSE {
WRITE "data input error"
QUIT
}
GOTO Young:age<30,Midage:(age>29)&(age<60),Elder:age>59
QUIT
Young
WRITE !,"你还年轻"
QUIT
Midage
WRITE !,"你正处于巅峰时期"
QUIT
Elder
WRITE !,"你有一生的智慧可以传授"
QUIT
还可以使用do
命令对此示例进行编码,以调用适当的子例程位置。不过,在这种情况下,当Caché遇到Quit
时,它会将控制权返回给DO
之后的命令。
下面的示例显示Offset
如何计算代码行。它计算插入的标签行和注释行;不计算空行:
Main
GOTO Branch+7
QUIT
Branch
WRITE "Line 1",!
SubBranch
WRITE "Line 3",!
/* comment line */
WRITE "Line 5",!
WRITE "Line 6",!
WRITE "Line 7",!
WRITE "Line 8",!
QUIT
注释占一行。Branch
开始数7行
DHC-APP>d Main^PHA.TEST.Command
Line 7
Line 8
把 GOTO Branch+7
改为 GOTO Branch+1
DHC-APP>d Main^PHA.TEST.Command
Line 1
Line 3
Line 5
Line 6
Line 7
Line 8
与do
命令不同,goto
无条件地转移控制权。当Caché在do
调用的子例程中遇到QUIT
时,它会将控制传递给最近的DO
之后的命令。
当Caché在GOTO
转移后遇到退出时,它不会将控制权交还给GOTO
之后的命令。如果前面有一个DO
,则它将控制权返回给最近一个DO
之后的命令。如果前面没有DO
,则返回到终端提示。
在以下代码序列中,C
中的QUIT
将控制权返回给A
中的DO
之后的WRITE
命令:
/// d ##class(PHA.TEST.Command).TestGOTO()
ClassMethod TestGOTO()
{
testgoto
A
WRITE !,"运行A"
DO B
WRITE !,"回到A,一切都完成了"
QUIT
B
WRITE !,"运行B"
GOTO C
WRITE !,"B中的此行不应执行"
QUIT
C
WRITE !,"运行C"
QUIT
}
DHC-APP>d ##class(PHA.TEST.Command).TestGOTO()
运行A
运行B
运行C
回到A,一切都完成了
GOTO
GOTO
可用于退出代码块,但不能用于进入代码块。
如果在For
、If
、Do While
或While
循环中使用GOTO
,则可以转到所有代码块外部的位置、当前代码块内的位置,或者从嵌套的代码块转到包围它的代码块中的位置。不能从一个代码块转到另一个代码块中的位置,无论是独立的代码块还是嵌套在当前代码块中的代码块。
转到代码块外部的位置将终止循环。转到代码块中的某个位置不会终止循环。从嵌套代码块到封闭代码块的GOTO
会终止内部(嵌套)循环,但不会终止外部循环。
GOTO
可用于退出TRY
或CATCH
代码块,但不能用于进入这些代码块之一。也不能将GOTO
指定为与TRY
或CATCH
关键字在同一行上的标签。尝试这样做会导致
错误。
GOTO
限制不允许执行以下GOTO
操作:
GOTO
进入或退出过程。DO
代码块中使用GOTO
在级别之间跳转。GOTO
不能与过程块内的名称间接(GOTO @NAME
)一起使用。