条件语句是为了根据不同特定条件执行不同的代码。
Swift 提供两种条件语句:if 与switch ,如果需要判断的条件较单纯或需要设置的条件较少时,可以使用 if ,反之则使用 switch 。
If
最简单的形式就是只有一个条件的表达式,而只有当这个条件表达式返回true的时候,才执行括号里面的代码,例子如下:
一个 if 语句,由一个布尔表达式后跟一个或多个语句组成。
let True = true
if True {
//如果布尔表达式为真将执行的语句
print("有的")
}
如果布尔表达式为 true,则 if 语句内的代码块将被执行。如果布尔表达式为 false,则 if 语句结束后的第一组代码(闭括号后)将被执行。
let someNumber = 2
if someNumber == 2 {
print("就是 2 ")
}
上述的说明就是,“someNumber等于2,是吗?”
是,就是true,就会执行打印;如果不是,就不会执行括号里面的代码。
如果当条件表达式返回false时,需要执行另一段代码,则使用else,如下:
if True { // 如果布尔表达式为真将执行的语句 } else { // 如果布尔表达式为假将执行的语句 }
else在英语的翻译是“别的”或“否则”。可以理解为,如果这样(满足第一个条件)…否则就那样(满足其他的条件)。
let number = 10
if number > 20 {
print ("数字大于 20")
} else {
print ("数字小于或等于 20")
}
// 打打印:数字小于或等于 20
上述的说明就是,“number大于2,是吗?”
返回false,也就是“不是”;所以执行“别的”代码块了。
else & else if 语句
一个 if 语句后面可跟着一个可选的 else if…else 语句,else if…else 语句在测试多个条件语句时是很有用的。
在这里…可能有点不容易理解,什么时候使用else?什么时候使用else if?以及真正的区别是什么。
当你使用 if , else if , else 语句时以下要点可以试着理解一下:
if 语句后可以有 0 个或 1 个 else,但是如果有 else if 语句,else 语句需要在 else if 语句之后。在 else if 语句之前,不可以有else 语句。
一旦 if 语句执行成功,其他的 else if 或 else 语句都不会执行。
有多个条件需要判断,可以用 else if 语句。
最后一个else会在所有条件都不成立(返回false)时被执行,如下:
let number2 = 100
if number2 < 20 {
print ("数字小于 20")
} else if number2 < 200 {
print ("数字不小于 20,但小于 200")
} else if number2 < 1000 {
print ("数字不小于 200,但小于 1000")
} else {
print ("数字不小于 1000")
}
// 打打印:数字不小于 20,但小于 200
上述代码中最后一个else不是一定要有,也可以省略,但就可能会没有返回true的条件表达式,例子如下:
let number3 = 10
if number3 > 50 {
print("number3 > 50")
} else if number3 > 200 {
print("number3 > 200")
}
// 这时候不会有东西被打打印来
既然没有满足任何的条件,就不会有代码被执行。
if 是吗1 {
/* 如果 是吗1 表达式为 true 则执行该语句 /
} else if 是吗2 {
/ 如果 是吗2 表达式为 true 则执行该语句 /
} else if 是吗3 {
/ 如果 是吗3 表达式为 true 则执行该语句 /
} else {
/ 如果以上所有条件表达式都不为 true 则执行该语句 */
}
想象一下,我们想要三条消息:一个在分数超过6000时,一个在正好6000时,一个在6000以下。我们可以这样写:
if score > 6000 {
print("分数超过 6000!")
} else {
if score == 6000 {
print("分数刚好 6000!")
} else {
print("分数低于 6000!")
}
}
上面的写法完全没问题,如果你想要这样写的话。
但是,我们可以使用 else if 使代码更易于阅读,这使我们将 else 与紧跟其后的 if 组合起来,如下所示:
if score > 6000 {
print("分数超过 6000!")
} else if score == 6000 {
print("分数刚好 6000!")
} else {
print("分数低于 6000!")
}
有了这样的优化,Swift会检查一次score,而且代码也更短,也更容易阅读。
可选绑定
使用可选绑定(optional binding)来判断可选类型是否有值,如果有值的话就指派给一个临时常量或临时变量,并执行其内部的代码,这个临时常量或变量只能在其内部使用。if跟while语句都可以使用可选绑定。格式如下:
if let 临时常量 = 可选类型 {
执行的代码
} else {
可选类型没有值 也就是 nil 时 执行的代码
}
以下是一个例子:
// 字符串内容是纯整数 所以经过转换后会是一个整数
let str = "123"
if let number = Int(str) {
print("字符串 \"\(str)\" 转换成一个整数 \(number)")
} else {
print("字符串 \"\(str)\" 不是一个整数")
}
// 如果字符串内容不是整数 转换后会返回 nil
let str2 = "It is a string ."
if let number = Int(str2) {
print("字符串 \"\(str2)\" 转换成一个整数 \(number)")
} else {
print("字符串 \"\(str2)\" 不是一个整数")
}
结合条件
Swift为我们提供了 && (与)和 || (或)同时检查多个条件。如果仅使用两个条件时,真的相当方便。
假设正在运行一个论坛,用户可以发布消息,也可以删除消息。
我们可能会写这样的代码:
let isOwner = true
let isEditingEnabled = false
let isAdmin = true
if isOwner == true || isAdmin == true {
print("你可以删除这篇文章")
}
if (isOwner == true && isEditingEnabled) || isAdmin == true {
print("你可以删除这篇文章")
}
也可以在单个条件下多次使用 && 和 || ,但不要让事情变得太复杂,否则你的代码可能会变成密码!
Switch
switch会将一个值与多个条件作比对,根据第一个比对成功的条件,会执行相对应的代码。所有 case 必须涵盖全部可能的条件,如果有未涵盖的部份,最后需要补上default。
最简单的格式如下:
switch 值 {
case 比对条件1:
相对应条件1 执行的代码
case 比对条件2, 比对条件3: // 多个条件可以用逗号 , 隔开
相对应条件2或条件3 执行的代码
default:
以上条件比对都不成功时 执行的代码
}
每个 case 中,都一定要有相对应执行的代码,如果没有的话就会报错误。
例子如下:
let number4 = 2
switch number4 {
case 1:
case 2:
print("It is 2 .")
case 3:
default:
print("没有比对到")
}
case 1 以及 case 3 内部都没有可执行的代码,所以就会报错。
有些程式语言的 switch 需要在每个 case 内的代码最后一行加上 break 来结束,否则会继续执行底下其他case中的代码。
Swift 则是相反。Swift 在遇到第一个条件 case 比对成功后,即马上结束 switch 这部份的动作。这种方式可以让 switch 使用的更安全及方便,也避免了因为忘记写 break 而产生的错误。
何时使用switch语句,而不是 if 语句?
- Swift 要求 switch 语句是要很清楚的,这意味着你必须有一个 case 区块来检查每个可能的值(例如枚举的所有 case),或者你必须有一个 default case。 这对于 if 和 else if 来说不是这样,因此你可能会不小心漏掉一个可能的值。
- 当你使用 switch 判断一个值是否有多个可能的结果时,该值将只需读取一次;而你使用 if 的时候,该值将多次读取。当你开始使用函数调用时,这个时候这一点就变得更加重要,因为其中的一些调用可能导致变慢。
- Swift 的 switch 允许高级模式匹配,而 if 则没有办法做复杂的匹配。
- 还有一种情况:基本来说,如果你想判断三个或三种以上的条件,可能大部分开发者更喜欢使用switch;不是为别的,就是单纯为了易读性,而不是为了编写更多复杂的条件。
Fallthrough 语句
以下是没有使用 fallthrough 语句的实例:
var index = 10
switch index {
case 100 :
print( "index 的值为 100")
case 10,15 :
print( "index 的值为 10 或 15")
case 5 :
print( "index 的值为 5")
default :
print( "默认 case")
}
以下实例使用 fallthrough 语句:
var index = 10
switch index {
case 100 :
print( "index 的值为 100")
fallthrough
case 10,15 :
print( "index 的值为 10 或 15")
fallthrough
case 5 :
print( "index 的值为 5")
default :
print( "默认 case")
}
加上 fallthrough 后进入到的下一个 case(或是default),不会做任何的条件做比对,而是直接执行下一个 case 里的代码。
区间匹配
case 中比对的条件也可以是一个区间:
let number5 = 130
var str3: String
switch number5 {
case 0...10:
str3 = "几"
case 11...100:
str3 = "很多"
case 101...1000:
str3 = "非常多"
default:
str3 = "超级多"
}
// 因为 120 在 101...1000 这个区间内
// 打印:我有非常多颗苹果
print("我有\(str3)颗苹果")
值绑定
case 可以将比对的值绑定(value binding)到一个临时的常量或变量,以便在其内的代码中使用:
let onePoint = (2, 0)
switch onePoint {
case (let x, 0):
print("在 X 轴上, x 的值为 \(x)")
case (0, let y):
print("在 Y 轴上, y 的值为 \(y)")
case let (x, y):
print("(\(x), \(y)) 不在 X 轴也不在 Y 轴上")
}
// 打印:在 X 轴上, x 的值为 2
另外可以使用where来判断额外的条件:
let number6 = 20
switch number6 {
case 1...100 where number6 == 50:
print("在 1...100 区间内 且值为 50")
case 1...100 where number6 == 20:
print("在 1...100 区间内 且值为 20")
default:
print("没有比对到")
}
Guard
有点类似 if 的用法,guard 同样会有一个条件表达式且会返回一个布尔值,不同的地方在于 guard 后面一定要接一个else,如果条件表达式返回 false 时,会执行{ }内的代码。
guard 条件表达式 else {
// 条件表达式返回 false 时 执行的代码
// 可以配合 continue, break 或 return 来控制转移流程
}
// 条件表达式返回 true 时 则继续执行接下来的代码
guard的英文意思是“守护”,或是“守卫”的意思。这个“守卫” guard 就会替你检查条件是否符合,然后判断是否执行里面的代码。
以下是一个例子:
// 建立一个名叫 post() 的函数
// 需要传入一个类型为 [String: String] 的字典
func post(article: [String: String]) {
// 首先取得传入字典中 键为 title 的值 并指派给一个常量
guard let insideTitle = article["title"] else {
// 如果没有键为 title 的值 这里面的代码就会被执行
// 函数中的 return 表示会直接结束这个函数
return
}
// 上面的 insideTitle 如果正确的被指派值 则会继续进行到这里
print("标题是 \(insideTitle) ,")
// 接着取得传入字典中 键为 content 的值 并指派给一个常量
guard let insideContent = article["content"] else {
// 如果没有键为 content 的值 这里面的代码就会被执行
print("但是没有内容。")
return
}
// 上面的 insideContent 如果有正确的被指派值 则会继续进行到这里
print("内容为 \(insideContent)。")
}
post(article: ["title": "Article_1"])
// 打印:标题是 Article_1 ,
// 打印:但是没有内容。
post(article: ["title":"Article_2","content":"Article_2_full_content"])
// 打印:标题是 Article_2 ,
// 打印:内容为 Article_2_full_content。
guard 条件表达式中,使用可选绑定而被指派的常量或变量,可以在函数{ }范围里接下来的代码中使用。
虽然guard用法与 if 类似,但使用guard可以一次专注于一种条件的条件,提高代码的可靠性,也可以让函数内容更清晰好读。