第十三章 Caché 命令大全 IF 命令

文章目录

十三章 Caché 命令大全 IF 命令

计算表达式,然后根据表达式的真值选择要执行的代码块。

重点

  1. 行语法即点语法,是早期语法。else可以省略为e
  2. 块语法,else不能省略。两者不应该混用。
  3. 块语法中,quit命令的区别。

大纲

IF expression1,... {
  code
}
ELSEIF expression2,... {
    code
}
ELSE {
    code
}
I expression1,... {
  code
}
ELSEIF expression2,... {
    code
}
ELSE {
    code
}

参数

  • expression1 IF子句的布尔测试条件。单个条件或逗号分隔的条件列表。
  • expression2 ELSEIF子句的布尔测试条件。单个条件或逗号分隔的条件列表。
  • code 用大括号括起来的CachéObjectScript命令块。

描述

本页介绍IFELSEIFELSE命令关键字,所有这些关键字都被视为IF命令的组件子句。

IF命令由一个IF子句、任意数量的ELSEIF子句和一个ELSEIF子句组成。ELSEIFELSE子句是可选的,但最好总是指定ELSE子句。

IF命令首先计算IF子句表达式1,如果表达式1为TRUE,则它执行紧随其后的大括号内的代码块,IF命令完成。

如果expression 1为false,则执行跳到if语句的下一个子句。它计算第一个ELSEIF子句(如果存在)。如果ELSEIF子句中的expression 2为true,则它执行紧随其后的大括号内的ELSEIF代码块,IF命令完成。如果expression 2为false,则以相同的方式计算下一个ELSEIF子句(如果存在)。按照列出的顺序测试每个连续的ELSEIF子句,直到其中一个子句测试为TRUE,或者所有子句测试为FALSE。

如果IF子句和所有ELSEIF子句的计算结果为FALSE,则继续执行ELSE子句。它执行紧随其后的花括号内的Else代码块,并且if命令完成。如果省略ELSE子句,则IF命令结束。

IF是面向块的命令。每个命令关键字后面都有一段用大括号括起来的代码块。ELSEIFELSE子句可以自由使用空格(换行符、缩进和空格)。但是,每个IFELSEIF关键字及其布尔测试表达式的第一个字符必须在同一行上,并由一个空格分隔。布尔测试表达式可以跨越多行并包含多个空格。

左大括号或右大括号可以出现在其自己的代码行上,也可以与命令显示在同一行上。左大括号或右大括号甚至可能出现在第1列中(但不建议这样做)。建议的编程实践是缩进大括号以指示嵌套代码块的开始和结束。左花括号前后不需要空格。右大括号前后不需要空格,包括无参数命令后的大括号。大括号只有一个空格要求:if命令最后一个子句的最后一个右大括号必须用空格、制表符或行回车符与后面的命令隔开。

注意:旧式应用程序中可能存在较早的、面向行的IF命令语法。这种面向行的IF形式不使用大括号,也不支持ELSEIF子句。这两种形式的if在语法上是不同的,不应该组合在一起。因此,一种类型的IF不应该与另一种类型的另一种类型的IF配对。前面面向行的Else可以缩写为E;面向块的Else关键字不能缩写。在面向块的IF嵌套在面向行的IF中的程序中,面向块的IF需要ELSE子句。

以下是有效语法:

/// d ##class(PHA.TEST.Command).TestIF()
ClassMethod TestIF()
{
	s x = 2,y = 2
	IF x=1 WRITE "x is 1",!
		IF y=1 { WRITE "y is 1",! }
		ELSE { WRITE "y is not 1",! }
	ELSE  WRITE "x is not 1",!
}

以下语法无效:

/// d ##class(PHA.TEST.Command).TestIF()
ClassMethod TestIFLine()
{
	s x =1,y=1 
	IF x=1 WRITE "x is 1"
		IF y=1 { WRITE "y is 1" }
	ELSE  WRITE "x is not 1"
}

最后一句编译不了

面向块的IF命令不读取或设置$TEST特殊变量的值。如果布尔测试表达式的计算结果为true,则无论$test的值是多少,它都会执行大括号内的代码块。

参数

expression1

IF子句的测试条件。它可以采用单个表达式的形式,也可以采用逗号分隔的表达式列表的形式。对于表达式列表,Caché按从左到右的顺序计算各个表达式。如果在逗号分隔的列表中遇到计算结果为False的表达式,它将停止计算。如果逗号分隔列表中的所有表达式的计算结果都为true,则Caché将执行与if子句关联的代码块。如果列表中的任何表达式的计算结果为false,则Caché将忽略任何剩余的表达式,并且不执行与if子句关联的代码块。

通常,expression 1是一个布尔表达式,计算结果为true或false(例如,x=7)。IF将文字值解释为布尔值TRUE和FALSE,如下所示:

  • True:任何非零数字值,或计算结果为非零数字值的数字字符串。例如1, 7, -.007, "7-7", "7dwarves".
  • False:零数值,或计算结果为零数值的字符串。非数字字符串的计算结果为零数值。例如,0, -0.00, 7-7, "0", "TRUE", "FALSE", "strike3", the empty string ("").

expression2

ELSEIF子句的测试条件。它可以采用单个表达式的形式,也可以采用逗号分隔的表达式列表的形式。它的计算方式与表达式1相同。

IF 使用 QUIT

如果在IF代码块(或ELSEIF代码块或ELSE代码块)中遇到QUIT命令,则QUIT的行为类似于常规的QUIT命令,就好像该代码块不存在一样。此行为不同于任何其他类型的大括号代码块内的退出(For、While、Do...While、Try或Catch)。

  • 如果IF代码块嵌套在循环结构(如FOR代码块)中,则QUIT退出循环结构块,并继续执行循环结构代码块后面的命令。
  • 如果IF代码块位于TRY块或CATCH块内,则QUIT将退出TRYCATCH块,并继续执行TRYCATCH块后面的命令。
  • 如果IF代码块未嵌套在循环结构中,或未嵌套在TRYCATCH块中,则QUIT退出当前例程。

发出Return将退出当前例程,无论它是否从块结构中发出。

下面的示例演示了IF不在循环结构中时的QUIT行为。退出将退出例程:

/// d ##class(PHA.TEST.Command).TestIFQuit()
ClassMethod TestIFQuit()
{
	SET y = $RANDOM(10)
	IF y # 2 = 0 {
		WRITE y," 偶数",!
		QUIT
		WRITE "不会w"
	}
	ELSE {
		WRITE y, " 奇数",!
		QUIT
		WRITE "不会w"
	}
	WRITE "退出IF(不会w)"
}
DHC-APP>d ##class(PHA.TEST.Command).TestIFQuit()
3 奇数
 
DHC-APP>d ##class(PHA.TEST.Command).TestIFQuit()
8 偶数

下面的示例演示了IF在循环结构中时的QUIT行为。Quit退出for循环,然后继续执行例程:

/// d ##class(PHA.TEST.Command).TestIFFor()
ClassMethod TestIFFor()
{
	FOR x = 1 : 1 : 8 {
		IF x # 2 = 0 {
			WRITE x," 偶数",!
			QUIT:x=4
		}
		ELSE {
			WRITE x," 奇数",!
		}
	}
	WRITE "退出IF(不会w)"
}

DHC-APP> d ##class(PHA.TEST.Command).TestIFFor()
1 奇数
2 偶数
3 奇数
4 偶数
退出IF(不会w)

下面的示例演示IFTRY块中时的QUIT行为。QUIT退出TRY块,然后继续执行例程,继续执行CATCH块之后的下一个代码:

/// d ##class(PHA.TEST.Command).TestIFCatch()
ClassMethod TestIFCatch()
{
	TRY {
		SET y = $RANDOM(10)
		IF y # 2 = 0 {
			WRITE y," 偶数",!
			QUIT
			WRITE "不会w"
		}
		ELSE {
			WRITE y," 奇数",!
			QUIT
			WRITE "不会w"
		}
		WRITE "退出IF(不会w)" 
	}
	CATCH exp1 {
		WRITE "仅在发生错误时写入",!
		WRITE "Error Name: ",$ZCVT(exp1.Name,"O","HTML"),!
	}
	TRY {
		WRITE "转到下一个TRY块"
	}
	CATCH exp2 {
		WRITE "仅在发生错误时写入",!
		WRITE "Error Name: ",$ZCVT(exp2.Name,"O","HTML"),!
	}
}
DHC-APP>d ##class(PHA.TEST.Command).TestIFCatch()
7 奇数
转到下一个TRY块
DHC-APP>d ##class(PHA.TEST.Command).TestIFCatch()
4 偶数
转到下一个TRY块

IF 使用 GOTO

如果在IF代码块中遇到GOTO,则程序执行遵循该语句,但有某些限制:

GOTO语句可以跳到IF命令之外的位置,也可以跳到当前子句的代码块内。GOTO语句不能跳转到另一个代码块:既不是属于当前IF命令的另一个子句的代码块,也不是属于另一个IF、FOR、DO WHILE或WHILE命令的代码块。

示例

在下面的示例中,if命令用于将响应器分类为三个组之一,并调用相应子例程。这三组人分别是44岁或以下的女性,44岁或以下的男性,以及45岁至120岁的女性或男性。

/// d ##class(PHA.TEST.Command).TestIFExample()
ClassMethod TestIFExample()
{
Mainloop
	READ !,"What is your sex? (M or F): ",!,sex QUIT:sex=""
	READ !,"What is your age? ",!,age QUIT:age=""
	IF "Ff"[sex,age<45 {
		DO SubA(age)
	}
	ELSEIF "Mm"[sex,age<45 {
		DO SubB(age)
	}
	ELSEIF "FfMm"[sex,age>44,age<125 {
		DO SubC(age)
	}
	ELSE {
	WRITE !,"Invalid data value input"
	}
SubA(y)
	WRITE !,"Young woman ",y," years old"
SubB(y)
	WRITE !,"Young man ",y," years old"
SubC(y)
	WRITE !,"Older person ",y," years old"
}
DHC-APP>d ##class(PHA.TEST.Command).TestIFExample()
 
What is your sex? (M or F):
M
What is your age?
30
Young man 30 years old
DHC-APP>d ##class(PHA.TEST.Command).TestIFExample()
 
What is your sex? (M or F):
F
What is your age?
99
Older person 99 years old

猜你喜欢

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