本节书摘来异步社区《Android游戏开发详解》一书中的第1章,第1.7节,作者: 【美】Jonathan S. Harbour 译者: 李强 责编: 陈冀康,更多章节内容可以访问云栖社区“异步社区”公众号查看。
1.7 控制流程第1部分——if和else语句
Android游戏开发详解
我们现在把注意力转向控制流程(control flow ,也称为流程控制,flow control),这指的是代码行将要按照什么样的顺序执行。还记得代码执行的基本规则吧,它是说代码要从上到下地执行。在最简单的程序中,代码真的是按照线性方式从上向下执行的。然而,在任何有用的程序中,我们可能会看到,根据某些条件,会跳过一些代码行甚至重复执行一些代码行。让我们来看一些例子。
1.7.1 if-else语句块
if-else语句块用来在代码中创建分支或多条路径。例如,我们可以检查如characterLevel > 10这样的条件来判断一个字符串内容,如图1-6所示。根据characterLevel的值,游戏可以执行不同的指令。你可以看到图1-4中有3条路径。
我们可以创建比上面的例子具有更多或更少分支的if-else语句块。实际上,我们甚至可以把if语句嵌套在其他的if语句中,以允许“内嵌的”分支。
1.7.2 if, else-if和else
无论何时,当你写下关键字if的时候,就开始了一个新的if-else语句块,如图1-6所示。你可以编写一个没有任何else-if或else语句的if语句块。这绝对没问题。
在你开始一个新的if-else语句块之后,每一个额外的else-if都表示一个新的分支。else语句是表示“我放弃”的分支,并且它将会为你处理所有的剩下的情况。
在给定的if-else语句块中,你只能选取一个分支。注意,在图1-6中,如果character Level是11,if和else-if语句中的条件似乎都满足。你可能会认为,这将会导致characterTitle变成“King”,随后很快又变成“Knight”。然而,不会发生这种情况,因为在if-else语句块中,你的代码只能选取一个分支,如图1-5所示。
1.7.3 函数和if-else语句块
再回来看看函数。实际上,我们可以通过if-else语句块使得函数更为强大。if-else语句块还是像前面所介绍的那样工作,但是现在,我们将其包含到函数中,这意味着,我们要留意更多的花括号。看看下面的示例函数,看能否确定哪个开始花括号对应哪个结束花括号。第一个示例中已经为你标识清楚了。
示例1
String theUltimateAnswer(boolean inBinary) {
String prefix = “The answer to life the universe and everything:”;
if (inBinary) {
return prefix + 101010;
} else {
return prefix + 42;
}
}
示例2
boolean isLessThanTen(int num) {
if (num < 10) {
return true;
} else {
return false;
}
}
示例3
boolean isEven(int num) {
if (num % 2 == 0) {
return true;
} else {
return false;
}
}
示例4
String desertSecurity(boolean hasGun, boolean hasRobots) {
if (hasGun) {
return "I've got a bad feeling about this.";
} else if (hasRobots) {
return "These are NOT the droids we are looking for."
} else {
return "Move along."
}
}
1.7.4 嵌套的if-else语句块
现在,我们必须掌握通过读取花括号来判断每个代码块从哪里开始以及从哪里结束的方法,让我们采取一些步骤。假设我们想要编写一个函数,它告诉我们一个人是否能够看一部限制级的电影(我们将根据资格返回true和false)。我们将设置如下所示的条件。
如果一个人拥有伪造的ID,他可以看该电影(不管其年龄多大)。
如果一个人有父母陪伴,他可以看该电影(不管其年龄多大)。
如果一个人没有伪造的ID或者没有父母陪伴:
如果这个人年龄达到了最小年龄,他可以看该电影。
如果这个人年龄尚未达到最小年龄,他不可以看该电影。
因此,我们必须将if-else语句嵌套(nest)到一个更为通用的条件之中,才能够处理没有伪造的ID或没有父母陪伴的人的情况。让我们来看看代码,从3个主要分支开始。
程序清单1.12 我能看电影吗(不完整版本)
1 boolean canWatch(int age, int minimumAge, boolean fakeID, boolean withParent) {
2 if (fakeID) {
3 return true;
4 } else if (withParent) {
5 return true;
6 } else {
7 // Nested if statements go here.
8 }
9 }
现在,在第3个分支中(else语句)添加两种特定的情况。
程序清单1.13 内部分支
if (age >= minimumAge) {
return true;
} else {
return false;
}
现在,我们可以将程序清单1.12和程序清单1.13放到一起,组成程序清单1.14。
程序清单1.14 我能看电影吗(完整版)
01 boolean canWatch(int age, int minimumAge, boolean fakeID, boolean withParent) {
02 if (fakeID) {
03 return true;
04 } else if (withParent) {
05 return true;
06 } else {
07 if (age >= minimumAge) {
08 return true;
09 } else {
10 return false;
11 }
12 }
13 }
1.7.5 简化布尔语句
尽管程序清单1.14中的代码能够很好地运行,我们还是可以进行一些优化,如程序清单1.15所示。
程序清单1.15 我能看电影吗(简化版#1)
01 boolean canWatch(int age, int minimumAge, boolean fakeID, boolean withParent) {
02 if (fakeID || withParent) { // Two cases were combined into one if statement.
03 return true;
04 } else {
05 if (age >= minimumAge) {
06 return true;
07 } else {
08 return false;
09 }
10 }
11 }
注意,在程序清单1.15中,我们在第2行使用“OR”运算符||将两种情况组合到一条if语句中。我们将所有的“true”的情况组合起来,以继续简化该函数,如程序清单1.16所示。
程序清单1.16 我能看电影吗(简化版#2)
01 boolean canWatch(int age, int minimumAge, boolean fakeID, boolean withParent) {
02 if (fakeID || withParent || age >= minimumAge) {
03 return true;
04 } else {
05 return false;
06 }
07 }
不管你是否相信,我们可以完全去除掉if-else语句块而只是返回(fakeID || withParent || age >= minimumAge)的值,从而更进一步简化,参见程序清单1.17。
程序清单1.17 我能看电影吗(简化版#3)
1 boolean canWatch(int age, int minimumAge, boolean fakeID, boolean withParent) {
2 return (fakeID || withParent || age >= minimumAge);
3 }
编写这样整洁的代码,就使得你(以及你的同事)能够更加高效地工作,而不需要使用诸如程序清单1.14那样复杂的逻辑。在整本书中,我们将学习到更多编写整洁代码的技巧。