终止例程的执行。
重要-
RETURN
总是退出当前例程,返回到调用例程,或者在没有调用例程的情况下终止程序。
RETURN:pc expression
RET:pc expression
参数
- pc 可选 - 后后置表达式
- expression 可选-CachéObjectScript表达式。
RETURN
命令用于终止例程的执行。在许多情况下,它是QUIT
命令的同义词。从FOR
,DO WHIL
E或WHILE
控制流结构或TRY
或CATCH
块中发出时,RETURN
和QUIT
有所不同。
- 可以使用
RETURN
在任何时候终止例程的执行,包括从FOR
,DO WHILE
或WHILE
循环或嵌套循环结构中执行。RETURN
总是退出当前例程,返回到调用例程,或者在没有调用例程的情况下终止程序。不管是否从代码块中发出,RETURN
的行为始终相同。这包括TRY
块或CATCH
块。 - 相反,当从
FOR
循环,DO WHILE
循环,WHILE
循环或TRY
或CATCH
块中发出时,QUIT
仅退出当前结构。QUIT
退出结构块,并使用该结构块外部的下一个命令继续执行当前例程。当在块结构之外或从IF
,ELSEIF
或ELSE
代码块中发出QUIT
时,退出当前例程。
RETURN
命令有两种形式:
- 无参
- 有参
后置条件不被视为参数。$ QUIT
特殊变量指示是否需要带参数的RETURN
命令才能从当前上下文中退出。为此提供了两个错误代码:M16“不允许带参数退出”和M17“带参数需要退出”。
无参数RETRUN
不带参数的RETURN
从当前上下文中退出而不返回值。它用于终止以DO
或XECUTE
命令启动的进程的执行级别。
如果在终端模式下给出了DO
,XECUTE
,则RETURN
将控制返回到终端模式。如果终止的进程在RETURN
之前包含NEW
命令,则RETURN
会自动杀死受影响的变量并将其恢复为原始值。
有参数RETRUN
RETURN
表达式终止用户定义的函数或对象方法,并返回指定表达式产生的值。带参数的RETURN
可用于从FOR
,DO WHILE
或WHILE
命令循环内,或从TRY
块或CATCH
块内退出例程。
如果在子例程中调用了带参数的RETURN
,则会发生以下情况之一:
- 如果在子例程(而不是函数)中调用了带参数的
RETURN
,则将对RETURN
参数进行计算(这可能会产生副作用或引发错误),并且将丢弃参数结果。执行返回到子例程的调用者。 - 如果子例程由
DO
命令调用并且在该DO
参数的范围内,则RETURN
命令将计算其参数(并且会发生该评估的任何副作用),但不会返回该参数。例如,DO
调用的以RETURN 4/0
结尾的子例程会生成错误。如果子例程由DO
调用且以参数RETURN
终止,而子例程以$ ETRAP
终止,则会发生相同的行为。
pc
可选的后置条件表达式。如果后置条件表达式为true(计算为非零数值),则Caché执行命令。如果后置条件表达式为假(评估为零),则Caché不执行命令。如果RETURN
命令不带其他参数,则后置条件和同一行中紧随其后的下一个命令之间必须有两个或多个空格。
expression
任何有效的CachéObjectScript表达式。它只能在用户定义的函数中使用,以将计算结果返回给调用例程。
示例以下两个示例对比了从控制流结构中发出时RETURN
和QUIT
的行为。RETURN
退出MySubroutine
,返回MyRoutine
。QUIT
退出FOR
循环,继续MySubroutine
的其余部分,然后返回MyRoutine
:
/// d ##class(PHA.TEST.Command).TestRetrun()
ClassMethod TestRetrun()
{
MyMain
WRITE "在主程序中",!
DO MySubroutine
WRITE "返回主程序",!
QUIT
MySubroutine
WRITE "在MySubroutine",!
FOR i=1:1:5 {
WRITE "FOR loop:",i,!
IF i=3 RETURN
WRITE " loop again",!
}
WRITE "MySubroutine行未与RETURN一起显示",!
QUIT
}
DHC-APP>d ##class(PHA.TEST.Command).TestRetrun()
在主程序中
在MySubroutine
FOR loop:1
loop again
FOR loop:2
loop again
FOR loop:3
返回主程序
/// d ##class(PHA.TEST.Command).TestRetrunQ()
ClassMethod TestRetrunQ()
{
MyMain
WRITE "在主程序中",!
DO MySubroutine
WRITE "返回主程序",!
QUIT
MySubroutine
WRITE "在MySubroutine",!
FOR i=1:1:5 {
WRITE "FOR loop:",i,!
IF i=3 QUIT
WRITE " loop again",!
}
WRITE "用QUIT显示MySubroutine行",!
QUIT
}
DHC-APP>d ##class(PHA.TEST.Command).TestRetrunQ()
在主程序中
在MySubroutine
FOR loop:1
loop again
FOR loop:2
loop again
FOR loop:3
用QUIT显示MySubroutine行
返回主程序
在以下示例中,第一个RETURN
命令的执行由后置条件(:x> 46
)控制。如果随机生成的数字大于46,则Caché不执行Cube
过程;第一个RETURN
采用后置条件,将一个字符串作为num
返回到调用例程。如果随机生成的数字小于或等于46,则第二个RETURN
返回num
形式的表达式x * x * x
的结果。
/// d ##class(PHA.TEST.Command).TestRetrunCube()
ClassMethod TestRetrunCube()
{
Main
SET x = $RANDOM(99)
WRITE "Number is: ",x,!
SET num=$$Cube(x)
WRITE "Cube is: ",num
QUIT
Cube(x) RETURN:x>46 "六位的数字."
WRITE "计算 cube",!
RETURN x*x*x
}
DHC-APP>d ##class(PHA.TEST.Command).TestRetrunCube()
Number is: 12
计算 cube
Cube is: 1728
DHC-APP>d ##class(PHA.TEST.Command).TestRetrunCube()
Number is: 74
Cube is: 六位的数字.
以下两个示例将QUIT
和RETURN
行为与TRY
和CATCH
进行了对比。TRY
块尝试除以零的操作,调用CATCH
块。该CATCH
块包含一个嵌套的TRY
块,该块由QUIT
或RETURN
退出。
RETURN
退出例程。因此,它退出嵌套的TRY
块和所有封闭的块,并且不执行TRY / CATCH
结构外部的fall-throug
行:
/// d ##class(PHA.TEST.Command).TestRetrunCal()
ClassMethod TestRetrunCal()
{
TRY {
WRITE "在TRY块中",!
SET x = 5/0
WRITE "此行不会显示"
}
CATCH exp1 {
WRITE "在CATCH块中",!
WRITE "Error Name: ",$ZCVT(exp1.Name,"O","HTML"),!
TRY {
WRITE "在嵌套的TRY块中",!
RETURN
}
CATCH exp2 {
WRITE "在嵌套的CATCH块中",!
WRITE "Error Name: ",$ZCVT(exp1.Name,"O","HTML"),!
}
WRITE "RETURN不显示此外部CATCH块行",!
}
WRITE "fall-through在程序结束"
}
DHC-APP>d ##class(PHA.TEST.Command).TestRetrunCal()
在TRY块中
在CATCH块中
Error Name: <DIVIDE>
在嵌套的TRY块中
QUIT
将嵌套的TRY
块退出到封闭块,并继续执行CATCH
块的其余部分。完成CATCH
块后,它将在TRY / CATCH
结构之外执行插入线:
/// d ##class(PHA.TEST.Command).TestRetrunCalQuit()
ClassMethod TestRetrunCalQuit()
{
TRY {
WRITE "在TRY块中",!
SET x = 5/0
WRITE "此行不会显示"
}
CATCH exp1 {
WRITE "在CATCH块中",!
WRITE "Error Name: ",$ZCVT(exp1.Name,"O","HTML"),!
TRY {
WRITE "在嵌套的TRY块中",!
QUIT
}
CATCH exp2 {
WRITE "在嵌套的CATCH块中",!
WRITE "Error Name: ",$ZCVT(exp1.Name,"O","HTML"),!
}
WRITE "QUIT显示此外部CATCH块行",!
}
WRITE "fall-through在程序结束"
}
DHC-APP>d ##class(PHA.TEST.Command).TestRetrunCalQuit()
在TRY块中
在CATCH块中
Error Name: <DIVIDE>
在嵌套的TRY块中
QUIT显示此外部CATCH块行
fall-through在程序结束
在此的示例RETURN
命令的参数是一个对象方法。 Caché终止方法的执行,并将控制权返回给调用例程。
RETURN inv.TotalNum()
注意
RETURN
恢复变量
如果终止的进程在RETURN
之前包含任何NEW
命令,则RETURN
会自动杀死受影响的变量并将其恢复为原始值。
隐式RETURN
在以下情况下,不需要RETURN
命令,因为Caché自动发出隐式RETURN
,以防止执行 “falling through” 到单独的代码单元。
- Caché在例程结束时执行隐式
RETURN
。 - 当Caché遇到带有参数的标签时,将执行隐式
RETURN
。即使括号中包含零个参数,带有参数的标签也被定义为带有括号的一个。所有过程均以带有参数的标签开头(即使未定义任何参数)。许多子例程和函数还带有带有参数的标签。
当然,可以在任何这些情况下编写一个显式的RETURN
。
与DO
的行为
当在由DO
命令调用的子例程中遇到时,RETURN
终止该子例程,并将控制权返回给DO
命令之后的命令。
与XECUTE
的行为
在正在执行的代码行中遇到RETURN
时,将终止该行的执行,并将控制权返回给XECUTE
命令之后的命令。不允许有参数。
用户定义方法的行为
当在用户定义的函数中遇到时,RETURN
会终止该函数并返回从指定表达式得出的值。表达式参数是必需的。
在使用中,用户定义的函数类似于带有参数传递的DO
命令。但是,它们与此类DO
命令的不同之处在于它们直接返回表达式的值,而不是通过变量返回。要调用用户定义的函数,请使用以下格式:
$$name(parameters)
其中,name
是函数的名称。可以将其指定为label
,^ routine
或label ^ routine
。
parameters是要传递给函数的参数的逗号分隔列表。与功能关联的标签还必须具有参数列表。被调用函数上的参数列表称为实际参数列表。功能标签上的参数列表称为形式参数列表。
终端堆栈清除级别
每次调用RETURN
都会从过程的调用堆栈中删除一个上下文框架。$ STACK
特殊变量包含调用堆栈上当前上下文帧的数量。
可以在终端提示下使用RETURN
来清除程序堆栈中的某些或所有级别。下面的示例清除堆栈中的前两个级别:
RETURN 2
无参数的RETURN清除堆栈中的所有级别。
使用RETURN提高程序可读性
Caché在每个例程的末尾执行一个隐式的RETURN
,但是可以显式地包括它以提高程序的可读性。