在之前的文章中,您学习了Swift编程语言的一些基本概念。 如果您之前已经编程过,我相信您会看到与其他编程语言(例如Ruby,JavaScript和Objective-C)的一些相似之处。
在本文中,我们将放大Swift中的控制流。 在更详细地讨论控制流之前,我们需要看一下对大多数人来说都是新概念,可选的。 可选项是Swift的另一个安全功能。 最初,使用可选选项看起来有些麻烦,但是您会很快了解到,可选选项将使您的代码更安全。
1.可选
我们已经看到,必须先初始化变量,然后才能使用它。 请看以下示例,以更好地理解其含义。
var str: String
str.isEmpty
如果您习惯在Objective-C中使用字符串,那么Swift会向您显示错误可能会让您感到惊讶。 让我们看看该错误告诉我们什么。
![一个错误](https://i-blog.csdnimg.cn/blog_migrate/0769aa52b641e90b34bf10f1dd61899a.png)
在许多语言中,变量具有初始默认值。 例如,在Objective-C中,以下代码段中的字符串等于nil
。
NSString *newString;
但是, nil
的概念在Swift和Objective-C中有所不同。 我们将在稍后详细讨论nil
。
什么是可选的?
Swift使用可选参数来封装一个重要的概念,即变量或常量具有值或没有值。 在Swift中就这么简单。 要将变量或常量声明为可选的,我们在变量或常量的类型后附加一个问号。
var str: String?
变量str
不再是String
类型。 现在它是可选 String
类型的。 了解这一点很重要。 结果或副作用是我们不能再直接与str
变量的值进行交互。 该值安全地存储在可选变量中,我们需要询问可选变量封装的值。
强制展开
访问可选值的一种方法是强制展开。 我们可以通过附加!
来访问变量str
的值!
到变量的名称。
var str: String?
str = "Test"
print(str!)
重要的是,在强制打开可选选项时,请确保该可选选项包含一个值。 如果可选参数没有值,而您强制将其拆开,则Swift会向您抛出错误。
![强制展开可选](https://i-blog.csdnimg.cn/blog_migrate/77b96239f96c9efcb4df348ff1fb293c.png)
可选装订
有一种更安全的方法来访问可选值。 我们将在几分钟后仔细查看if
语句,但是以下示例显示了我们如何安全地访问存储在变量str
的值,该变量为可选String
类型。
var str: String?
if str != nil {
print(str!)
} else {
print("str has no value")
}
我们先检查变量str
是否等于nil
然后再打印其内容。 在此示例中, str
没有值,这意味着它不会被意外打开。
有一种更优雅的方法称为可选绑定。 在下面的示例中,我们将可选参数中存储的值分配给一个临时常量,该常量在if
语句中使用。 可选str
值绑定到常量strConst
并在if
语句中使用。 这种方法也适用于while
语句。
var str: String?
str = "Test"
if let strConst = str {
print(strConst)
} else {
print("str has no value")
}
什么是nil
?
如果您来自Objective-C,那么您肯定会知道nil
是什么。 在Objective-C中, nil
是指向不存在的对象的指针。 Swift对nil
的定义略有不同,因此了解差异非常重要。
在Swift中, nil
表示不存在任何值。 虽然nil
仅适用于Objective-C中的对象,但在Swift中nil
可用于任何类型。 因此,重要的是要理解,在Objective-C中,可选不是nil
的等效项。 这些概念非常不同。
2.控制流程
Swift提供了许多常见的构造来控制您编写的代码的流程。 如果您有任何编程经验,那么使用Swift的控制流构造,条件if
和switch
语句以及for
和while
循环就不会有问题。
但是,如果Swift的控制流程与例如Objective-C的控制流程构造没有什么不同,它就不会是Swift。 尽管细节很重要,但我相信它们不会妨碍您快速掌握Swift。 让我们从最常见的条件构造if
语句开始。
if
Swift的if
语句与Objective-C中的语句非常相似。 主要区别在于无需将条件包装在括号中。 但是,必须使用大括号。 后者阻止开发人员引入与编写if
语句不带花括号有关的常见错误。 这就是Swift中的if
语句。
let a = 10
if a > 10 {
print("The value of \"a\" is greater than 10.")
} else {
print("The value of \"a\" is less than or equal to 10.")
}
Swift还定义了else
子句也就不足为奇了。 如果条件等于false
则执行else
子句中的代码。 也可以链接if
语句,如下面的示例所示。
let a = 10
if a > 10 {
print("The value of \"a\" is greater than 10.")
} else if a > 5 {
print("The value of \"a\" is greater than 5.")
} else {
print("The value of \"a\" is less than or equal to 5.")
}
需要注意的一个重要事项是, if
语句的条件需要返回true
或false
。 对于Objective-C中的if
语句,情况并非如此。 看一下Objective-C中的以下if
语句。
NSArray *array = @[];
if (array.count) {
NSLog(@"The array contains one or more items.");
} else {
NSLog(@"The array is empty.");
}
如果要将上面的代码片段移植到Swift,则会遇到错误。 该错误不是很有用,但是Swift确实告诉我们,我们需要确保条件的结果为true
或false
。
![控制流量误差](https://i-blog.csdnimg.cn/blog_migrate/7aed16a3b0f32700f522514c0a43b280.png)
将上面的Objective-C代码片段转换为Swift的正确方法是,确保if
语句的条件为true
或false
,如以下代码片段所示。
let array = [String]()
if array.count > 0 {
print("The array contains one or more items.")
} else {
print("The array is empty.")
}
switch
Swift的switch
语句比其Objective-C等效功能更强大。 稍后您将学习,它也更安全。 尽管存在一些差异,但是Swift中的switch
语句遵循与其他编程语言相同的概念; 一个值被传递到switch
语句,并与可能的匹配模式进行比较。
是的,模式。 如我所说,Swift中的switch
语句有一些技巧。 我们稍后将看一下这些技巧。 让我们先谈谈安全性。
详尽的
Swift中的switch
语句需要详尽无遗,这意味着传递给switch
语句的类型的每个可能值都需要由switch
语句处理。 与在Objective-C中一样,可以通过添加default
情况来轻松解决此问题,如以下示例所示。
let a = 10
switch a {
case 0:
print("a is equal to 0")
case 1:
print("a is equal to 1")
default:
print("a has another value")
}
跌倒
与Objective-C的switch
语句实现的一个重要区别是缺少隐式失败。 以下示例由于某些原因在Swift中不起作用。
let a = 10
switch a {
case 0:
case 1:
print("a is equal to 1")
default:
print("a has another value")
}
将a
与0
比较的第一种情况并不隐含地归结为a
与1
比较的第二种情况。 如果将上述示例添加到操场上,您会注意到Swift会向您抛出错误。 该错误表明,每种情况都需要至少包含一个可执行语句。
请注意, switch
语句的用例不包含break
语句以脱离switch
语句。 在Swift中这不是必需的,因为在Swift中不存在隐式失败。 这将消除因意外掉线引起的一系列常见错误。
模式
Swift中switch
语句的功能在于模式匹配。 看下面的示例,在该示例中,我使用范围来比较考虑的值。
let a = 10
switch a {
case 0..<5:
print("The value of a lies between 0 and 4.")
case 5...10:
print("The value of a lies between 5 and 10.")
default:
print("The value of a is greater than 10.")
}
..<
运算符或半开范围运算符定义从第一值到第二值的范围,不包括第二值。 ...
运算符或封闭范围运算符定义从第一值到第二值(包括第二值)的范围。 这些运算符在很多情况下都非常有用。
您还可以将switch
语句的考虑值与元组进行比较。 看下面的例子,看看它是如何工作的。
let latlng = (34.15, -78.03)
switch latlng {
case (0, 0):
print("We're at the center of the planet.")
case (0...90, _):
print("We're in the Northern hemisphere.")
case (-90...0, _):
print("We're in the Southern hemisphere.")
default:
print("The coordinate is invalid.")
}
如上例所示,该值可能匹配多个情况。 发生这种情况时,将选择第一个匹配的情况。 上面的示例还说明了下划线的用法。 正如我们在上一篇文章中看到的,我们可以使用下划线_
来告诉Swift我们对哪些值不感兴趣。
价值绑定
值绑定也可以通过switch
语句进行,如以下示例所示。 元组的第二个值临时绑定到常量description
以用于第一种和第二种情况。
var response = (200, "OK")
switch response {
case (200..<400, let description):
print("The request was successful with description \(description).")
case (400..<500, let description):
print("The request was unsuccessful with description \(description).")
default:
print("The request was unsuccessful with no description.")
}
for
for
循环是我们将要研究的第一个循环构造。 它的行为与其他语言中的for
循环非常相似。 过去有两种形式, for
循环和for-in
循环。 从Swift 3开始,C风格的for
循环不再可用。 以下代码段在Swift 3中不可用。
for var i = 0; i < 10; i++ {
print("i is equal to \(i).")
}
如果将此代码段粘贴到操场上,您还会注意到++
和--
运算符在Swift 3中不再可用。
for-in
循环非常适合循环范围或集合的内容。 在下面的示例中,我们遍历数组的元素。
let numbers = [1, 2, 3, 5, 8]
for number in numbers {
print("number is equal to \(number)")
}
我们还可以使用for-in
循环来循环字典的键值对。 在下面的示例中,我们声明一个字典并将其内容打印到控制台。 如本系列前面所述,键值对的序列是不确定的,因为字典是键值对的无序集合。
var bids = ["Tom": 100, "Bart": 150, "Susan": 120]
for (name, bid) in bids {
print("\(name)'s bid is $\(bid).")
}
字典中的每个键值对都可以在for-in
循环中作为已命名常量的元组使用。 结合范围, for-in
循环也很棒。 我确定您同意以下代码段易于阅读和理解,这要归功于使用封闭范围。
for i in 1...10 {
print("i is equal to \(i)")
}
while
while
循环有两种形式, while
和repeat-while
。 主要区别在于, repeat-while
循环的语句集始终至少执行一次,因为repeat-while
循环的条件在每次迭代结束repeat-while
进行评估。 以下示例说明了这种差异。
var c = 5
var d = 5
while c < d {
print("c is smaller than d")
}
repeat {
print("c is smaller than d")
} while c < d
while
循环的print语句从不执行,而repeat-while
循环的print语句仅执行一次。
在许多情况下, for
循环可以重写为while
循环,并且通常由开发人员确定在特定情况下使用哪种循环类型。 以下for
和while
循环导致相同的输出。
for i in 0..<10 {
print(i)
}
var i = 0
while i < 10 {
print(i)
i += 1
}
结论
与我们在本文中介绍的内容相比,Swift中的流程控制要多得多,但是您现在已经具备了基本的知识,可以继续进行Swift之旅了。 我希望本教程向您展示了Swift的控制流实现与其他编程语言的实现非常相似,但又有所不同。
在本系列的其余部分中,我们将更多地使用Swift的控制流构造,并且您将逐渐更好地理解Swift和诸如Objective-C之类的语言之间的细微差异。 在本系列的下一部分中,我们将开始探索功能。
翻译自: https://code.tutsplus.com/tutorials/swift-from-scratch-optionals-and-control-flow--cms-22874