From 2da452f6bf267018ae0555c338f11f5099b40579 Mon Sep 17 00:00:00 2001 From: shanks Date: Fri, 11 Nov 2016 21:08:36 +0800 Subject: [PATCH] 02,basic operators, for 3.0.1 --- source/chapter2/02_Basic_Operators.md | 91 ++++++++++++--------------- 1 file changed, 41 insertions(+), 50 deletions(-) diff --git a/source/chapter2/02_Basic_Operators.md b/source/chapter2/02_Basic_Operators.md index cac08640..b13cdc56 100755 --- a/source/chapter2/02_Basic_Operators.md +++ b/source/chapter2/02_Basic_Operators.md @@ -12,7 +12,8 @@ > 校对:[shanks](http://codebuild.me) > 2.2 -> 翻译+校对:[Cee](https://github.com/Cee) 校对:[SketchK](https://github.com/SketchK),2016-05-11 +> 翻译+校对:[Cee](https://github.com/Cee) 校对:[SketchK](https://github.com/SketchK),2016-05-11 +> 3.0.1,shanks,2016-11-11 本页包含内容: @@ -26,29 +27,29 @@ - [区间运算符](#range_operators) - [逻辑运算符](#logical_operators) -运算符是检查、改变、合并值的特殊符号或短语。例如,加号(`+`)将两个数相加(如 `let i = 1 + 2`)。更复杂的运算例子包括逻辑与运算符 `&&`(如 `if enteredDoorCode && passedRetinaScan`)。 +*运算符*是检查、改变、合并值的特殊符号或短语。例如,加号(`+`)将两个数相加(如 `let i = 1 + 2`)。更复杂的运算例子包括逻辑与运算符 `&&`(如 `if enteredDoorCode && passedRetinaScan`)。 Swift 支持大部分标准 C 语言的运算符,且改进许多特性来减少常规编码错误。如:赋值符(`=`)不返回值,以防止把想要判断相等运算符(`==`)的地方写成赋值符导致的错误。算术运算符(`+`,`-`,`*`,`/`,`%`等)会检测并不允许值溢出,以此来避免保存变量时由于变量大于或小于其类型所能承载的范围时导致的异常结果。当然允许你使用 Swift 的溢出运算符来实现溢出。详情参见[溢出运算符](../chapter2/25_Advanced_Operators.html#overflow_operators)。 -区别于 C 语言,在 Swift 中你可以对浮点数进行取余运算(`%`),Swift 还提供了 C 语言没有的表达两数之间的值的区间运算符(`a.. ## 术语 -运算符分为一元、二元和三元运算符。 +运算符分为一元、二元和三元运算符: -- 一元运算符对单一操作对象操作(如 `-a`)。一元运算符分前置运算符和后置运算符,前置运算符需紧跟在操作对象之前(如 `!b`),后置运算符需紧跟在操作对象之后(如 `c!`)。 -- 二元运算符操作两个操作对象(如 `2 + 3`),是中置的,因为它们出现在两个操作对象之间。 -- 三元运算符操作三个操作对象,和 C 语言一样,Swift 只有一个三元运算符,就是三目运算符(`a ? b : c`)。 +- *一元*运算符对单一操作对象操作(如 `-a`)。一元运算符分前置运算符和后置运算符,*前置运算符*需紧跟在操作对象之前(如 `!b`),*后置运算符*需紧跟在操作对象之后(如 `c!`)。 +- *二元*运算符操作两个操作对象(如 `2 + 3`),是*中置*的,因为它们出现在两个操作对象之间。 +- *三元*运算符操作三个操作对象,和 C 语言一样,Swift 只有一个三元运算符,就是三目运算符(`a ? b : c`)。 -受运算符影响的值叫操作数,在表达式 `1 + 2` 中,加号 `+` 是二元运算符,它的两个操作数是值 `1` 和 `2`。 +受运算符影响的值叫*操作数*,在表达式 `1 + 2` 中,加号 `+` 是二元运算符,它的两个操作数是值 `1` 和 `2`。 ## 赋值运算符 -赋值运算(`a = b`),表示用 `b` 的值来初始化或更新 `a` 的值: +*赋值运算符*(`a = b`),表示用 `b` 的值来初始化或更新 `a` 的值: ```swift let b = 10 @@ -77,7 +78,7 @@ if x = y { ## 算术运算符 -Swift 中所有数值类型都支持了基本的四则算术运算: +Swift 中所有数值类型都支持了基本的四则*算术运算符*: - 加法(`+`) - 减法(`-`) @@ -101,10 +102,10 @@ Swift 中所有数值类型都支持了基本的四则算术运算: ### 求余运算符 -求余运算(`a % b`)是计算 `b` 的多少倍刚刚好可以容入`a`,返回多出来的那部分(余数)。 +*求余运算符*(`a % b`)是计算 `b` 的多少倍刚刚好可以容入`a`,返回多出来的那部分(余数)。 > 注意: -求余运算(`%`)在其他语言也叫取模运算。然而严格说来,我们看该运算符对负数的操作结果,「求余」比「取模」更合适些。 +求余运算符(`%`)在其他语言也叫*取模运算符*。然而严格说来,我们看该运算符对负数的操作结果,「求余」比「取模」更合适些。 我们来谈谈取余是怎么回事,计算 `9 % 4`,你先计算出 `4` 的多少倍会刚好可以容入 `9` 中: @@ -142,22 +143,10 @@ Swift 中所有数值类型都支持了基本的四则算术运算: 在对负数 `b` 求余时,`b` 的符号会被忽略。这意味着 `a % b` 和 `a % -b` 的结果是相同的。 -### 浮点数求余计算 - -不同于 C 语言和 Objective-C,Swift 中是可以对浮点数进行求余的。 - -```swift -8 % 2.5 // 等于 0.5 -``` - -这个例子中,`8` 除以 `2.5` 等于 `3` 余 `0.5`,所以结果是一个 `Double` 型的值为 `0.5`。 - -![Art/remainderFloat_2x.png](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Art/remainderFloat_2x.png "Art/remainderFloat_2x.png") - ### 一元负号运算符 -数值的正负号可以使用前缀 `-`(即一元负号)来切换: +数值的正负号可以使用前缀 `-`(即*一元负号符*)来切换: ```swift let three = 3 @@ -165,24 +154,24 @@ let minusThree = -three // minusThree 等于 -3 let plusThree = -minusThree // plusThree 等于 3, 或 "负负3" ``` -一元负号(`-`)写在操作数之前,中间没有空格。 +一元负号符(`-`)写在操作数之前,中间没有空格。 ### 一元正号运算符 -一元正号(`+`)不做任何改变地返回操作数的值: +*一元正号符*(`+`)不做任何改变地返回操作数的值: ```swift let minusSix = -6 let alsoMinusSix = +minusSix // alsoMinusSix 等于 -6 ``` -虽然一元 `+` 什么都不会改变,但当你在使用一元负号来表达负数时,你可以使用一元正号来表达正数,如此你的代码会具有对称美。 +虽然一元正号符什么都不会改变,但当你在使用一元负号来表达负数时,你可以使用一元正号来表达正数,如此你的代码会具有对称美。 ## 组合赋值运算符 -如同 C 语言,Swift 也提供把其他运算符和赋值运算(`=`)组合的组合赋值运算符,组合加运算(`+=`)是其中一个例子: +如同 C 语言,Swift 也提供把其他运算符和赋值运算(`=`)组合的*组合赋值运算符*,组合加运算(`+=`)是其中一个例子: ```swift var a = 1 @@ -195,12 +184,12 @@ a += 2 > 注意: 复合赋值运算没有返回值,`let b = a += 2`这类代码是错误。这不同于上面提到的自增和自减运算符。 -在[表达式](../chapter3/04_Expressions.html)章节里有复合运算符的完整列表。 +在[Swift 标准库运算符参考](https://developer.apple.com/reference/swift/1851035-swift_standard_library_operators)章节里有复合运算符的完整列表。 ‌ ## 比较运算符(Comparison Operators) -所有标准 C 语言中的比较运算都可以在 Swift 中使用: +所有标准 C 语言中的*比较运算符*都可以在 Swift 中使用: - 等于(`a == b`) - 不等于(`a != b`) @@ -247,13 +236,15 @@ if name == "world" { (4, "dog") == (4, "dog") // true,因为 4 等于 4,dog 等于 dog ``` -> 注意: +在上面的例子中,你可以看到,在第一行中从左到右的比较行为。因为`1`小于`2`,所以`(1, "zebra")`小于`(2, "apple")`,不管元组剩下的值如何。所以`"zebra"`小于`"apple"`没有任何影响,因为元组的比较已经被第一个元素决定了。不过,当元组的第一个元素相同时候,第二个元素将会用作比较-第二行和第三行代码就发生了这样的比较。 + +>注意: Swift 标准库只能比较七个以内元素的元组比较函数。如果你的元组元素超过七个时,你需要自己实现比较运算符。 ## 三目运算符(Ternary Conditional Operator) -三目运算符的特殊在于它是有三个操作数的运算符,它的形式是 `问题 ? 答案 1 : 答案 2`。它简洁地表达根据 `问题`成立与否作出二选一的操作。如果 `问题` 成立,返回 `答案 1` 的结果;反之返回 `答案 2` 的结果。 +*三目运算符*的特殊在于它是有三个操作数的运算符,它的形式是 `问题 ? 答案 1 : 答案 2`。它简洁地表达根据 `问题`成立与否作出二选一的操作。如果 `问题` 成立,返回 `答案 1` 的结果;反之返回 `答案 2` 的结果。 三目运算符是以下代码的缩写形式: @@ -295,7 +286,7 @@ if hasHeader { ## 空合运算符(Nil Coalescing Operator) -空合运算符(`a ?? b`)将对可选类型 `a` 进行空判断,如果 `a` 包含一个值就进行解封,否则就返回一个默认值 `b`。表达式 `a` 必须是 Optional 类型。默认值 `b` 的类型必须要和 `a` 存储值的类型保持一致。 +*空合运算符*(`a ?? b`)将对可选类型 `a` 进行空判断,如果 `a` 包含一个值就进行解封,否则就返回一个默认值 `b`。表达式 `a` 必须是 Optional 类型。默认值 `b` 的类型必须要和 `a` 存储值的类型保持一致。 空合运算符是对以下代码的简短表达方法: @@ -306,7 +297,7 @@ a != nil ? a! : b 上述代码使用了三目运算符。当可选类型 `a` 的值不为空时,进行强制解封(`a!`),访问 `a` 中的值;反之返回默认值 `b`。无疑空合运算符(`??`)提供了一种更为优雅的方式去封装条件判断和解封两种行为,显得简洁以及更具可读性。 > 注意: -如果 `a` 为非空值(`non-nil`),那么值 `b` 将不会被计算。这也就是所谓的短路求值。 +如果 `a` 为非空值(`non-nil`),那么值 `b` 将不会被计算。这也就是所谓的*短路求值*。 下文例子采用空合运算符,实现了在默认颜色名和可选自定义颜色名之间抉择: @@ -332,10 +323,10 @@ colorNameToUse = userDefinedColorName ?? defaultColorName ## 区间运算符(Range Operators) -Swift 提供了两个方便表达一个区间的值的运算符。 +Swift 提供了两个方便表达一个区间的值的*区间运算符*。 ### 闭区间运算符 -闭区间运算符(`a...b`)定义一个包含从 `a` 到 `b`(包括 `a` 和 `b`)的所有值的区间。`a` 的值不能超过 `b`。 +*闭区间运算符*(`a...b`)定义一个包含从 `a` 到 `b`(包括 `a` 和 `b`)的所有值的区间。`a` 的值不能超过 `b`。 ‌ 闭区间运算符在迭代一个区间的所有值时是非常有用的,如在 `for-in` 循环中: @@ -354,8 +345,8 @@ for index in 1...5 { ### 半开区间运算符 -半开区间(`a.. -## 逻辑运算(Logical Operators) +## 逻辑运算符(Logical Operators) -逻辑运算的操作对象是逻辑布尔值。Swift 支持基于 C 语言的三个标准逻辑运算。 +*逻辑运算符*的操作对象是逻辑布尔值。Swift 支持基于 C 语言的三个标准逻辑运算。 - 逻辑非(`!a`) - 逻辑与(`a && b`) - 逻辑或(`a || b`) -### 逻辑非 +### 逻辑非运算符 -逻辑非运算(`!a`)对一个布尔值取反,使得 `true` 变 `false`,`false` 变 `true`。 +*逻辑非运算符*(`!a`)对一个布尔值取反,使得 `true` 变 `false`,`false` 变 `true`。 它是一个前置运算符,需紧跟在操作数之前,且不加空格。读作 `非 a` ,例子如下: @@ -400,11 +391,11 @@ if !allowedEntry { 在示例代码中,小心地选择布尔常量或变量有助于代码的可读性,并且避免使用双重逻辑非运算,或混乱的逻辑语句。 -### 逻辑与 +### 逻辑与运算符 -逻辑与(`a && b`)表达了只有 `a` 和 `b` 的值都为 `true` 时,整个表达式的值才会是 `true`。 +*逻辑与运算符*(`a && b`)表达了只有 `a` 和 `b` 的值都为 `true` 时,整个表达式的值才会是 `true`。 -只要任意一个值为 `false`,整个表达式的值就为 `false`。事实上,如果第一个值为 `false`,那么是不去计算第二个值的,因为它已经不可能影响整个表达式的结果了。这被称做「短路计算(short-circuit evaluation)」。 +只要任意一个值为 `false`,整个表达式的值就为 `false`。事实上,如果第一个值为 `false`,那么是不去计算第二个值的,因为它已经不可能影响整个表达式的结果了。这被称做*短路计算(short-circuit evaluation)*。 以下例子,只有两个 `Bool` 值都为 `true` 的时候才允许进入 if: @@ -419,11 +410,11 @@ if enteredDoorCode && passedRetinaScan { // 输出 "ACCESS DENIED" ``` -### 逻辑或 +### 逻辑或运算符 -逻辑或(`a || b`)是一个由两个连续的 `|` 组成的中置运算符。它表示了两个逻辑表达式的其中一个为 `true`,整个表达式就为 `true`。 +逻辑或运算符(`a || b`)是一个由两个连续的 `|` 组成的中置运算符。它表示了两个逻辑表达式的其中一个为 `true`,整个表达式就为 `true`。 -同逻辑与运算类似,逻辑或也是「短路计算」的,当左端的表达式为 `true` 时,将不计算右边的表达式了,因为它不可能改变整个表达式的值了。 +同逻辑与运算符类似,逻辑或也是「短路计算」的,当左端的表达式为 `true` 时,将不计算右边的表达式了,因为它不可能改变整个表达式的值了。 以下示例代码中,第一个布尔值(`hasDoorKey`)为 `false`,但第二个值(`knowsOverridePassword`)为 `true`,所以整个表达是 `true`,于是允许进入: @@ -440,7 +431,7 @@ if hasDoorKey || knowsOverridePassword { ### 逻辑运算符组合计算 -我们可以组合多个逻辑运算来表达一个复合逻辑: +我们可以组合多个逻辑运算符来表达一个复合逻辑: ```swift if enteredDoorCode && passedRetinaScan || hasDoorKey || knowsOverridePassword {