Swift5.2-基本的操做(中文文档)

引言

继续学习Swift文档,从上一章节:基础,咱们学习了Swift基础,如今,咱们学习Swift的基本操做。这一章节的内容比较简单,一些运算符操做基本上和C、OC上的同样,不过在Swift上也有它特有的一些运算符,能够简化代码,如**??操做符、...操做符、..<**操做符和单边值域,不熟悉的朋友能够单独去看这部份内容(在七、八、9三个小节),其余的运算符就能够跳过了。因为篇幅较长,这里分篇来记录,接下来,开始吧!html

若是你已经掌握了Swift的基础,那么请参阅下一章节:字符串和字符swift

基本的操做

运算符是用于检查、更改或组合值的特殊符号或短语。例如,加法运算符(+)将两个数字相加,如let i = 1 + 2;逻辑和运算符(&&)组合两个布尔值,如if enteredDoorCode && passedRetinaScan。数组

Swift支持大多数标准的C操做符,并改进了一些功能,以消除常见的编码错误。赋值操做符(=)不返回值,以防止在使用equal to操做符(==)时错误地使用它。算术运算符(+、-、*、/、%等等)检测并禁止值溢出,以免在处理大于或小于存储它们的类型容许的值范围的数字时出现意外结果。您可使用Swift的溢出操做符(如溢出操做符中所述)来选择对溢出行为进行值设置。bash

Swift还提供了C中没有的范围操做符,好比a..< b和a…b做为表示值范围的快捷方式。app

本章介绍了Swift中经常使用的操做符。高级操做符涵盖Swift的操做符,并描述如何定义您本身自定义操做符和实现标准操做符为您本身自定义类型。less

1 术语

运算符有一元、二元或三元:ide

  • 一元操做符对单个目标(好比-a)进行操做。一元前缀操做符当即出如今它们的目标(好比!b)以前,一元后缀操做符当即出如今它们的目标(好比c!)以后。
  • 二元操做符对两个目标(例如2 + 3)进行操做,而且是中缀,由于它们出如今两个目标之间。
  • 三元运算符对三个目标进行操做。和C同样,Swift只有一个三元运算符,三元条件运算符(a ? b : c)。

操做符影响的值是操做数。在表达式1 + 2中,+符号是一个二元运算符,它的两个操做数是值1和2。post

2 赋值运算符

赋值操做符(a = b)初始化或更新a的值为b:学习

let b = 10
var a = 5
a = b
// a is now equal to 10
复制代码

若是赋值的右边是一个有多个值的元组,那么它的元素能够一次分解为多个常量或变量:测试

let (x, y) = (1, 2)
// x is equal to 1, and y is equal to 2
复制代码

与C和Objective-C中的赋值操做符不一样,Swift中的赋值操做符自己不返回值。如下陈述无效:

if x = y {
    // This is not valid, because x = y does not return a value.
}
复制代码

该特性防止在实际使用equal to操做符(==)时意外使用赋值操做符(=)。经过设置if x = y无效,Swift能够帮助您避免代码中出现这类错误。

3 算术运算符

针对数值类型,Swift提供了四种基本的算术运算符:

  • 加法(+)
  • 减法(-)
  • 乘法 (*)
  • 除法 (/)
1 + 2       // equals 3
5 - 3       // equals 2
2 * 3       // equals 6
10.0 / 2.5  // equals 4.0
复制代码

与C和Objective-C中的算术运算符不一样,Swift算术运算符默认不容许值溢出。您能够选择使用Swift的溢出操做符(如a &+ b)来计算溢出行为的值。请参阅溢出操做符

字符串链接也支持加法运算符:

"hello, " + "world"  // equals "hello, world"
复制代码

3.1 余数操做符

余数运算符(a % b)计算出a中能够容纳多少个b的倍数,并返回剩余的值(称为余数)。

注意 余数运算符(%)在其余语言中也称为模运算符。可是,它在负数中的表现意味着,严格地说,它是一个余数而不是模运算。

下面是余数运算符的工做原理。要计算9 % 4,你首先要算出9能装下多少个4s:

../_images/remainderInteger_2x.png

能够在9中放入两个4s,余数为1(用橙色表示)。

在Swift中能够这样写:

9 % 4    // equals 1
复制代码

为了肯定a % b的答案,%运算符计算如下等式并返回余数做为输出:

a = (b x some multiplier) + remainder
复制代码

some multiplier是a中b的最大倍数。

将9和4插入到这个方程,获得:

9 = (4 x 2) + 1
复制代码

计算a的负值的余数时采用相同的方法:

-9 % 4   // equals -1
复制代码

将-9和4插入方程,获得:

-9 = (4 x -2) + -1
复制代码

余数为-1。

当b为负值时,b的符号被忽略。这意味着a % b和a % -b老是给出相同的答案。

3.2 一元减(-)操做符

数字值的符号能够经过前缀-来进行切换,也就是一元减运算符:

let three = 3
let minusThree = -three       // minusThree equals -3
let plusThree = -minusThree   // plusThree equals 3, or "minus minus three"
复制代码

一元减运算符(-)直接放在它所操做的值前面,没有任何空格。

3.3 一元加(+)操做符

一元加号运算符(+)只返回它所操做的值,没有任何变化:

let minusSix = -6
let alsoMinusSix = +minusSix  // alsoMinusSix equals -6
复制代码

虽然一元加号运算符实际上没有任何做用,可是您能够在代码中使用它来为正数提供对称,同时也可使用一元减号运算符来为负数提供对称。

4 复合赋值操做符

像C同样,Swift提供了将赋值(=)与另外一个操做组合起来的复合赋值操做符。一个例子是加法赋值操做符(+=):

var a = 1
a += 2
// a is now equal to 3
复制代码

表达式a += 2是a = a + 2的简写。有效地,加法和赋值被合并到一个运算符中,同时执行两个任务。

注意 复合赋值操做符不返回值。例如,你不能写b = a += 2。

有关Swift标准库提供的操做符的信息,请参见操做符声明

5 比较运算符

Swift支持全部标准C比较运算符:

  • 等于(a == b)
  • 不等于(a != b)
  • 大于(a > b)
  • 小于(a < b)
  • 大于等于(a >= b)
  • 小于等于(a <= b)

注意 Swift还提供了两个身份操做符(===和!==),用于测试两个对象引用是否都引用同一个对象实例。有关更多信息,请参见标识操做符

每一个比较运算符都返回一个Bool值来表示语句是否为真:

1 == 1   // true because 1 is equal to 1
2 != 1   // true because 2 is not equal to 1
2 > 1    // true because 2 is greater than 1
1 < 2    // true because 1 is less than 2
1 >= 1   // true because 1 is greater than or equal to 1
2 <= 1   // false because 2 is not less than or equal to 1
复制代码

比较运算符经常使用于条件语句中,如if语句:

let name = "world"
if name == "world" {
    print("hello, world")
} else {
    print("I'm sorry \(name), but I don't recognize you")
}
// Prints "hello, world", because name is indeed equal to "world".
复制代码

有关If更多内容,请参阅控制流

若是两个元组具备相同的类型和相同数量的值,则能够比较它们。元组从左到右进行比较,一次一个值,直到比较发现两个不相等的值为止。比较这两个值,比较的结果决定元组比较的整体结果。若是全部元素都相等,则元组自己也相等。例如:

(1, "zebra") < (2, "apple")   // true because 1 is less than 2; "zebra" and "apple" are not compared
(3, "apple") < (3, "bird")    // true because 3 is equal to 3, and "apple" is less than "bird"
(4, "dog") == (4, "dog")      // true because 4 is equal to 4, and "dog" is equal to "dog"
复制代码

在上面的示例中,您能够在第一行看到从左到右的比较行为。由于1小于2,因此(1,“zebra”)被认为小于(2,“apple”),而与元组中的其余值无关。“zebra”不小于“apple”并不重要,由于比较已经由元组的第一个元素决定了。可是,当元组的第一个元素相同时,将比较它们的第二个元素—这是在第二和第三行发生的事情。

只有当运算符能够应用于相应元组中的每一个值时,才能将元组与给定的运算符进行比较。例如,以下面的代码所示,您能够比较类型(String, Int)的两个元组,由于字符串和Int值均可以使用<操做符进行比较。相反,类型的两个元组(String、Bool)不能与<操做符进行比较,由于<操做符不能应用于Bool值。

("blue", -1) < ("purple", 1)        // OK, evaluates to true
("blue", false) < ("purple", true)  // Error because < can't compare Boolean values 复制代码

注意 Swift标准库包含元组比较运算符,用于元素少于七个的元组。要比较具备7个或更多元素的元组,必须本身实现比较运算符。

6 元条件运算符

三元条件运算符是一种特殊的运算符,由三部分组成:question ?answer1 : answer2。这是一个计算两个表达式中的一个的捷径,基于问题是真的仍是假的。若是question为真,它计算answer1并返回它的值;不然,它将计算answer2并返回其值。

三元条件运算符是如下代码的简写:

if question {
    answer1
} else {
    answer2
}
复制代码

下面是一个示例,它计算表行的高度。若是行有标题,行高应该比内容高50点,若是行没有标题,行高20点:

let contentHeight = 40
let hasHeader = true
let rowHeight = contentHeight + (hasHeader ? 50 : 20)
// rowHeight is equal to 90
复制代码

上面代码是下面代码的简写:

let contentHeight = 40
let hasHeader = true
let rowHeight: Int
if hasHeader {
    rowHeight = contentHeight + 50
} else {
    rowHeight = contentHeight + 20
}
// rowHeight is equal to 90
复制代码

第一个示例使用了三元条件运算符,这意味着能够在一行代码中将rowh8设置为正确的值,这比第二个示例中使用的代码更简洁。

三元条件运算符提供了一种有效的简写方式来决定两个表达式中的哪个要考虑。可是,使用三元条件运算符时要当心。若是过分使用,它的简洁性会致使难以阅读的代码。避免将三元条件运算符的多个实例组合成一个复合语句。

7 Nil-Coalescing操做符( ??操做符 )

nil-coalescing操做符(a ?? b)若是一个可选的a包含一个值,则展开它;若是a为nil,则返回一个默认值b。表达式a始终是可选类型。表达式b必须匹配存储在a中的类型。

Nil-Coalescing操做符是下面代码的简写:

a != nil ? a! : b
复制代码

上面的代码使用三元条件运算符和强制展开(a!),当a不是nil时访问包装在a中的值,不然返回b。nil-coalescing操做符提供了一种更优雅的方式,以简洁和可读的形式封装这种条件检查和展开。

注意 若是a的值是非nil,那么b的值就不会被计算。这就是所谓的短路评估。

下面的例子使用了nil-coalescing操做符来选择默认的颜色名称和可选的用户定义的颜色名称:

let defaultColorName = "red"
var userDefinedColorName: String?   // defaults to nil

var colorNameToUse = userDefinedColorName ?? defaultColorName
// userDefinedColorName is nil, so colorNameToUse is set to the default of "red"
复制代码

userDefinedColorName变量被定义为一个可选字符串,默认值为nil。由于userDefinedColorName是可选类型,因此可使用nil-coalescing操做符来考虑它的值。在上面的示例中,操做符用于肯定名为colorNameToUse的字符串变量的初始值。由于userDefinedColorName是nil,表达式userDefinedColorName ??defaultColorName返回defaultColorName的值,或者“red”。

若是你给userDefinedColorName分配一个非nil值,并再次执行nl -coalescing操做符检查,userDefinedColorName内的值将被使用,而不是默认值:

userDefinedColorName = "green"
colorNameToUse = userDefinedColorName ?? defaultColorName
// userDefinedColorName is not nil, so colorNameToUse is set to "green"
复制代码

8 范围操做符

Swift包括几个范围操做符,它们是表示值范围的快捷方式。

8.1 封闭范围运算符 ( ... 操做符 )

闭值域运算(a…b)定义了从a到b的值域,包括a和b的值。a的值不能大于b。

闭合范围运算符在迭代一个范围时很是有用,在这个范围内你须要使用全部的值,例如forin循环:

for index in 1...5 {
    print("\(index) times 5 is \(index * 5)")
}
// 1 times 5 is 5
// 2 times 5 is 10
// 3 times 5 is 15
// 4 times 5 is 20
// 5 times 5 is 25
复制代码

关于更多for-in循环,参阅控制流

8.2 半开范围操做符( ..< 操做符)

半开区间运算符(a..<b)定义了从a到b的范围,但不包括b。之因此称之为半开区间,是由于它包含了第一个值,但没有包含最终值。与封闭范围操做符同样,a的值不能大于b。若是a的值等于b,那么结果范围将为空。

当你处理基于0的列表(好比数组)时,半开的范围特别有用,这里有用的是计算列表的长度(但不包括):

let names = ["Anna", "Alex", "Brian", "Jack"]
let count = names.count
for i in 0..<count {
    print("Person \(i + 1) is called \(names[i])")
}
// Person 1 is called Anna
// Person 2 is called Alex
// Person 3 is called Brian
// Person 4 is called Jack
复制代码

注意,数组包含4个项,可是0..<count只计算到3(数组中最后一项的索引),由于它是半开放的范围。有关数组的更多信息,请参见数组

8.3 单边值域

对于在一个方向上尽量连续的范围,封闭范围操做符有另外一种形式—例如,包含数组从索引2到数组末尾的全部元素的范围。在这些状况下,能够忽略范围操做符一侧的值。这种值域称为单边值域,由于运算符只有一边有值。例如:

for name in names[2...] {
    print(name)
}
// Brian
// Jack

for name in names[...2] {
    print(name)
}
// Anna
// Alex
// Brian
复制代码

半开式值域运算符也有一个单边形式,只有它的最终值。就像在两边都包含值同样,最终值也不属于范围内。例如:

for name in names[..<2] {
    print(name)
}
// Anna
// Alex
复制代码

单边值域能够在其余上下文中使用,而不只仅是下标。您不能遍历遗漏第一个值的单边值域,由于不清楚迭代应该从哪里开始。您能够迭代一个单边的值域,省略其最终值;可是,因为范围是无限延续的,因此请确保为循环添加了一个显式的结束条件。还能够检查单边值域是否包含特定值,以下面的代码所示。

let range = ...5
range.contains(7)   // false
range.contains(4)   // true
range.contains(-1)  // true
复制代码

9 逻辑运算符

逻辑运算符修改或组合布尔逻辑值true和false。Swift支持基于c语言的三种标准逻辑运算符:

  • 逻辑 非 (!a)
  • 逻辑 与 (a && b)
  • 逻辑 或 (a || b)

9.1 逻辑非运算符

逻辑非操做符(!a)反转布尔值,使真变为假,假变为真。

逻辑非操做符是一个前缀操做符,它出如今它所操做的值的前面,没有任何空格。能够理解为“非 a”,以下例所示:

let allowedEntry = false
if !allowedEntry {
    print("ACCESS DENIED")
}
// Prints "ACCESS DENIED"
复制代码

“if !allowedEntry”能够理解为“if not allowed entry”。后面的行只在“not allowed entry”为真时执行;也就是说,若是allowedEntry为false。

与本例同样,谨慎选择布尔常量和变量名有助于保持代码可读性和简洁,同时避免双重否认或逻辑语句混乱。

9.2 逻辑与运算符

逻辑和运算符(a && b)建立逻辑表达式,其中两个值必须为真,整个表达式也为真。

若是任一值为假,则整个表达式也为假。事实上,若是第一个值为假,第二个值甚至不会计算,由于它不可能使整个表达式等于真。这就是所谓的短路评估。

这个例子考虑了两个Bool值,只有当两个值都为真时才容许访问:

let enteredDoorCode = true
let passedRetinaScan = false
if enteredDoorCode && passedRetinaScan {
    print("Welcome!")
} else {
    print("ACCESS DENIED")
}
// Prints "ACCESS DENIED"
复制代码

9.3 逻辑或运算符

逻辑或操做符(|| b)是由两个相邻管道字符组成的中缀操做符。您可使用它来建立逻辑表达式,其中两个值中只有一个必须为真才能使整个表达式为真。

与上面的逻辑和运算符同样,逻辑或运算符使用短路求值来考虑其表达式。若是逻辑或表达式的左边为真,则不计算右边的值,由于它不能改变整个表达式的结果。

在下例中,第一个Bool值(hasDoorKey)为假,但第二个值(knowsOverridePassword)为真。由于一个值为真,整个表达式的计算结果也为真,所以容许访问:

let hasDoorKey = false
let knowsOverridePassword = true
if hasDoorKey || knowsOverridePassword {
    print("Welcome!")
} else {
    print("ACCESS DENIED")
}
// Prints "Welcome!"
复制代码

9.4 组合的逻辑运算符

您能够组合多个逻辑运算符来建立更长的复合表达式:

if enteredDoorCode && passedRetinaScan || hasDoorKey || knowsOverridePassword {
    print("Welcome!")
} else {
    print("ACCESS DENIED")
}
// Prints "Welcome!"
复制代码

这个示例使用多个&&和||操做符建立一个更长的复合表达式。可是,&&和||操做符仍然只对两个值进行操做,所以这其实是三个链接在一块儿的较小的表达式。这个例子能够理解为:

若是咱们输入了正确的门码而且经过了视网膜扫描,或者若是咱们有一个有效的门钥匙,或者若是咱们知道紧急控制密码,那么就容许进入。

根据enteredDoorCode、passedRetinaScan和hasDoorKey的值,前两个子表达式为false。可是,紧急覆盖密码是已知的,所以整个复合表达式的计算结果仍然为true。

注意 Swift逻辑运算符&&和||是左关联的,这意味着包含多个逻辑运算符的复合表达式首先计算最左边的子表达式。

9.5 用括号分隔多个逻辑运算符

有时,若是不是严格须要括号,那么包含括号是颇有用的,这样可使复杂表达式的意图更容易理解。在上面的door access示例中,在复合表达式的第一部分周围添加括号以明确其意图是颇有用的:

if (enteredDoorCode && passedRetinaScan) || hasDoorKey || knowsOverridePassword {
    print("Welcome!")
} else {
    print("ACCESS DENIED")
}
// Prints "Welcome!"
复制代码

括号清楚地代表前两个值被视为整个逻辑中单独可能的状态的一部分。复合表达式的输出没有变化,但整体意图对读者更清晰。可读性老是比简洁更重要;使用括号来帮助明确你的意图。

总结

这一章节的内容比较简单,一些运算符操做基本上和C、OC上的同样,不过在Swift上也有它特有的一些运算符,能够简化代码,以下所示:

  • ?? 操做符
  • 封闭范围操做符(...) 、半开范围操做符(..<) 和单边值域

具体的做用,能够翻看上面的内容找到答案。

最后,喜欢的朋友能够打个star哦!这样我才更有动力继续下去,嘎嘎嘎~

上一章节:基础

下一章节:字符串和字符

参考文档:Swift - Basic Operators

相关文章
相关标签/搜索