第十章 Caché 命令大全 GOTO 命令

第十章 Caché 命令大全 GOTO 命令

转移控制权。

重点

  1. ObjectScript 无法直接使用 GOTO 间接符,和偏移量, mac可以。
  2. ObjectScript goto只可以到例程标签名字

大纲

GOTO:pc
GOTO:pc goargument,...

G:pc
G:pc goargument,...

其中,goargument是:

location:pc

参数

  • pc 可选-后置条件表达式。
  • location 可选-控制权将转移到的点。

描述

GOTO命令有两种形式:

  • 有参数
  • 无参数

GOTO 无参数

不带参数的goto在Caché在当前执行的代码中遇到错误或中断命令后恢复正常的程序执行。只能在终端提示符下使用无参数GOTO

下面的示例显示了无参数GOTO的用法。在此示例中,由于<Break>错误而未执行第二次写入;发出GOTO命令将继续执行,执行第二次写入:

DHC-APP>WRITE "before" BREAK  WRITE "after"
before
WRITE "before" BREAK  WRITE "after"
               ^
<BREAK>
DHC-APP 1S0>goto
after

请注意,BREAK命令后必须有两个空格。

如果在发出无参数GOTONEW命令生效,则Caché会发出<command>错误,并保留新上下文。使用Quit 1命令,然后使用无参数GOTO在新操作后继续。

也可以在终端提示符下使用无参数 GOTO,以便在出错后继续执行。

GOTO 有参数

带有参数location的goto将控制转移到指定位置。如果在命令或参数上指定后置条件表达式,则仅当后置条件表达式的计算结果为true(非零)时,Caché才会转移控制权。

可以从编程模式提示符使用转到位置在不同位置恢复中断的程序。

可以将$CASE函数指定为GOTO命令参数。

参数

pc

可使命令具有条件的可选后置条件表达式。如果后置条件表达式附加到GOTO命令关键字后,如果后置条件表达式为TRUE(计算结果为非零数值),则Caché将执行GOTO命令。如果后置条件表达式为假(计算结果为零),则Caché不执行GOTO命令。如果后置条件表达式附加到参数后,如果后置条件表达式为TRUE(计算结果为非零数值),则Caché将执行该参数。如果后置条件表达式为假(计算结果为零),则Caché跳过该参数并计算下一个参数(如果有)或下一个命令。

location

控制权将转移到的点。它在例程代码中是必需的。在编程器模式提示符下是可选的。可以将位置指定为单个值或逗号分隔的值列表(带有后置条件),并且可以采用以下任何形式:

  • Label+Offset指定当前例程内的行标签。可选的+offset是一个非负整数,它指定开始执行的标签之后的行数。Offset计算代码行(包括标签行),并计算注释行;Offset不计算空行和注释内的空行。但是,OFFSET确实计算所有嵌入的SQL行,包括所有空行。

  • label+offset^routine 在指定的例程中指定行标签,该例程驻留在磁盘上。Caché从磁盘加载例程,并在指定的标签处继续执行。可选的+offset 是一个非负整数,它指定开始执行的标签之后的行数。

  • ^ROUTINE指定驻留在磁盘上的例程。Caché从磁盘加载例程,并在例程内的第一行可执行代码处继续执行。如果例程已修改,则当GOTO调用例程时,Caché加载例程的更新版本。与DO命令不同,GOTO在例程执行后不会返回到调用程序。如果指定的例程不存在,则Caché会发出<NOROUTINE>错误消息。

注意:GOTO不支持扩展例程引用。要在另一个命名空间中执行例程,请使用do命令。

还可以将LOCATION作为包含上述任何表单的变量进行引用。不过,在这种情况下,必须使用名称间接。location 不能指定使用形参列表或用户定义的函数或过程的名称定义的子例程标签。如果指定的标签不存在,则Caché会发出<NOLINE>错误消息。

调用CACHESYS%例程时不能指定偏移量。如果尝试这样做,Caché会发出<NOLINE>错误。

示例

在下面的示例中,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可用于退出代码块,但不能用于进入代码块。

如果在ForIfDo WhileWhile循环中使用GOTO,则可以转到所有代码块外部的位置、当前代码块内的位置,或者从嵌套的代码块转到包围它的代码块中的位置。不能从一个代码块转到另一个代码块中的位置,无论是独立的代码块还是嵌套在当前代码块中的代码块。

转到代码块外部的位置将终止循环。转到代码块中的某个位置不会终止循环。从嵌套代码块到封闭代码块的GOTO会终止内部(嵌套)循环,但不会终止外部循环。

GOTO可用于退出TRYCATCH代码块,但不能用于进入这些代码块之一。也不能将GOTO指定为与TRYCATCH关键字在同一行上的标签。尝试这样做会导致<NOLINE>错误。

GOTO限制

不允许执行以下GOTO操作:

  • 不应使用GOTO进入或退出过程。
  • 不应在嵌套的无参数DO代码块中使用GOTO在级别之间跳转。
  • GOTO不能与过程块内的名称间接(GOTO @NAME)一起使用。

猜你喜欢

转载自blog.csdn.net/yaoxin521123/article/details/107242490
今日推荐