Merge pull request #464 from 949478479/master

更新了“基础部分 - 输出常量和变量” 中“print(_:separator:terminator:)”函数描述。
This commit is contained in:
梁杰
2015-09-06 09:11:55 +08:00
3 changed files with 223 additions and 199 deletions

View File

@ -149,23 +149,14 @@ languageName = "Swift++"
<a name="printing"></a> <a name="printing"></a>
### 输出常量和变量 ### 输出常量和变量
你可以用`print(_:)`函数来输出当前常量或变量的值: 你可以用`print(_:separator:terminator:)`函数来输出当前常量或变量的值:
```swift ```swift
print(friendlyWelcome) print(friendlyWelcome)
// 输出 "Bonjour!" // 输出 "Bonjour!"
``` ```
`print(_:)`是一个用来输出的全局函数,输出的内容会在最后换行。如果你用 Xcode`print(_:)`将会输出内容到“console”面板上。(另一种函数叫`print(_:appendNewline:)`,唯一区别是在输出内容最后不会换行。) `print(_:separator:terminator:)`是一个用来输出一个或多个值到适当输出区的全局函数。如果你用 Xcode`print(_:separator:terminator:)`将会输出内容到“console”面板上。`separator`和`terminator`参数具有默认值,因此你调用这个函数的时候可以忽略它们。默认情况下,该函数通过添加换行符来结束当前行。如果不想换行,可以传递一个空字符串给`terminator`参数--例如,`print(someValue, terminator:"")`。关于参数默认值的更多信息,请参考[默认参数值](./06_Functions.html#default_parameter_values)。
`print(_:)`函数输出传入的`String`值:
```swift
print("This is a string")
// 输出 "This is a string"
```
`print(_:)`函数可以输出更复杂的信息。这些信息可以包含当前常量和变量的值。
Swift 用字符串插值string interpolation的方式把常量名或者变量名当做占位符加入到长字符串中Swift 会用当前常量或变量的值替换这些占位符。将常量或变量名放入圆括号中,并在开括号前使用反斜杠将其转义: Swift 用字符串插值string interpolation的方式把常量名或者变量名当做占位符加入到长字符串中Swift 会用当前常量或变量的值替换这些占位符。将常量或变量名放入圆括号中,并在开括号前使用反斜杠将其转义:
@ -223,7 +214,7 @@ Swift 提供了81632和64位的有符号和无符号整数类型。这些
<a name="integer_bounds"></a> <a name="integer_bounds"></a>
### 整数范围 ### 整数范围
你可以访问不同整数类型的`min`和`max`属性来获取对应类型的最值和最值: 你可以访问不同整数类型的`min`和`max`属性来获取对应类型的最值和最值:
```swift ```swift
let minValue = UInt8.min // minValue 为 0是 UInt8 类型 let minValue = UInt8.min // minValue 为 0是 UInt8 类型
@ -239,7 +230,7 @@ let maxValue = UInt8.max // maxValue 为 255是 UInt8 类型
* 在32位平台上`Int`和`Int32`长度相同。 * 在32位平台上`Int`和`Int32`长度相同。
* 在64位平台上`Int`和`Int64`长度相同。 * 在64位平台上`Int`和`Int64`长度相同。
除非你需要特定长度的整数,一般来说使用`Int`就够了。这可以提高代码一致性和可复用性。即使是在32位平台上`Int`可以存储的整数范围也可以达到`-2147483648`~`2147483647`,大多数时候这已经足够大了。 除非你需要特定长度的整数,一般来说使用`Int`就够了。这可以提高代码一致性和可复用性。即使是在32位平台上`Int`可以存储的整数范围也可以达到`-2,147,483,648`~`2,147,483,647`,大多数时候这已经足够大了。
<a name="UInt"></a> <a name="UInt"></a>
### UInt ### UInt
@ -272,7 +263,7 @@ Swift 是一个类型安全type safe的语言。类型安全的语言可
由于 Swift 是类型安全的所以它会在编译你的代码时进行类型检查type checks并把不匹配的类型标记为错误。这可以让你在开发的时候尽早发现并修复错误。 由于 Swift 是类型安全的所以它会在编译你的代码时进行类型检查type checks并把不匹配的类型标记为错误。这可以让你在开发的时候尽早发现并修复错误。
当你要处理不同类型的值时类型检查可以帮你避免错误。然而这并不是说你每次声明常量和变量的时候都需要显式指定类型。如果你没有显式指定类型Swift 会使用_类型推断type inference来选择合适的类型。有了类型推断编译器可以在编译代码的时候自动推断出表达式的类型。原理很简单只要检查你赋的值即可。 当你要处理不同类型的值时类型检查可以帮你避免错误。然而这并不是说你每次声明常量和变量的时候都需要显式指定类型。如果你没有显式指定类型Swift 会使用_类型推断_type inference来选择合适的类型。有了类型推断编译器可以在编译代码的时候自动推断出表达式的类型。原理很简单只要检查你赋的值即可。
因为有类型推断,和 C 或者 Objective-C 比起来 Swift 很少需要声明类型。常量和变量虽然需要明确类型,但是大部分工作并不需要你自己来完成。 因为有类型推断,和 C 或者 Objective-C 比起来 Swift 很少需要声明类型。常量和变量虽然需要明确类型,但是大部分工作并不需要你自己来完成。
@ -430,7 +421,7 @@ var maxAmplitudeFound = AudioSample.min
<a name="booleans"></a> <a name="booleans"></a>
## 布尔值 ## 布尔值
Swift 有一个基本的布尔Boolean类型叫做`Bool`。布尔值指逻辑上的logical因为它们只能是真或者假。Swift 有两个布尔常量,`true`和`false` Swift 有一个基本的布尔Boolean类型叫做`Bool`。布尔值指逻辑上的因为它们只能是真或者假。Swift 有两个布尔常量,`true`和`false`
```swift ```swift
let orangesAreOrange = true let orangesAreOrange = true
@ -551,17 +542,17 @@ print("The status message is \(http200Status.description)")
> 注意: > 注意:
C 和 Objective-C 中并没有可选类型这个概念。最接近的是 Objective-C 中的一个特性,一个方法要不返回一个对象要不返回`nil``nil`表示“缺少一个合法的对象”。然而,这只对对象起作用——对于结构体,基本的 C 类型或者枚举类型不起作用。对于这些类型Objective-C 方法一般会返回一个特殊值(比如`NSNotFound`来暗示值缺失。这种方法假设方法的调用者知道并记得对特殊值进行判断。然而Swift 的可选类型可以让你暗示_任意类型_的值缺失并不需要一个特殊值。 C 和 Objective-C 中并没有可选类型这个概念。最接近的是 Objective-C 中的一个特性,一个方法要不返回一个对象要不返回`nil``nil`表示“缺少一个合法的对象”。然而,这只对对象起作用——对于结构体,基本的 C 类型或者枚举类型不起作用。对于这些类型Objective-C 方法一般会返回一个特殊值(比如`NSNotFound`来暗示值缺失。这种方法假设方法的调用者知道并记得对特殊值进行判断。然而Swift 的可选类型可以让你暗示_任意类型_的值缺失并不需要一个特殊值。
来看一个例子。Swift 的`String`类型有一个叫做`toInt`的方法,作用是将一个`String`值转换成一个`Int`值。然而,并不是所有的字符串都可以转换成一个整数。字符串`"123"`可以被转换成数字`123`,但是字符串`"hello, world"`不行。 来看一个例子。Swift 的`String`类型有一种构造器,作用是将一个`String`值转换成一个`Int`值。然而,并不是所有的字符串都可以转换成一个整数。字符串`"123"`可以被转换成数字`123`,但是字符串`"hello, world"`不行。
下面的例子使用`toInt`方法来尝试将一个`String`转换成`Int` 下面的例子使用这种构造器来尝试将一个`String`转换成`Int`
```swift ```swift
let possibleNumber = "123" let possibleNumber = "123"
let convertedNumber = possibleNumber.toInt() let convertedNumber = Int(possibleNumber)
// convertedNumber 被推测为类型 "Int?" 或者类型 "optional Int" // convertedNumber 被推测为类型 "Int?" 或者类型 "optional Int"
``` ```
因为`toInt`方法可能会失败所以它返回一个_可选类型optional`Int`,而不是一个`Int`。一个可选的`Int`被写作`Int?`而不是`Int`。问号暗示包含的值是可选类型,也就是说可能包含`Int`值也可能不包含值。(不能包含其他任何值比如`Bool`值或者`String`值。只能是`Int`或者什么都没有。) 因为该构造器可能会失败所以它返回一个_可选类型_optional`Int`,而不是一个`Int`。一个可选的`Int`被写作`Int?`而不是`Int`。问号暗示包含的值是可选类型,也就是说可能包含`Int`值也可能不包含值。(不能包含其他任何值比如`Bool`值或者`String`值。只能是`Int`或者什么都没有。)
<a name="nil"></a> <a name="nil"></a>
### nil ### nil
@ -591,9 +582,9 @@ Swift 的`nil`和 Objective-C 中的`nil`并不一样。在 Objective-C 中,`n
<a name="if"></a> <a name="if"></a>
### if 语句以及强制解析 ### if 语句以及强制解析
你可以使用`if`语句和nil比较来判断一个可选值是否包含值。你可以使用“相等”(==)或“不等”(!=)来执行比较。 你可以使用`if`语句和`nil`比较来判断一个可选值是否包含值。你可以使用“相等”(`==`)或“不等”(`!=`)来执行比较。
如果可选类型有值它将不等于nil: 如果可选类型有值,它将不等于`nil`:
```swift ```swift
if convertedNumber != nil { if convertedNumber != nil {
@ -601,7 +592,7 @@ if convertedNumber != nil {
} }
// 输出 "convertedNumber contains some integer value." // 输出 "convertedNumber contains some integer value."
``` ```
当你确定可选类型确实包含值之后,你可以在可选的名字后面加一个感叹号(`!`来获取值。这个惊叹号表示“我知道这个可选有值请使用它。”这被称为可选值的_强制解析forced unwrapping 当你确定可选类型确实包含值之后,你可以在可选的名字后面加一个感叹号(`!`来获取值。这个惊叹号表示“我知道这个可选有值请使用它。”这被称为可选值的_强制解析_forced unwrapping
```swift ```swift
if convertedNumber != nil { if convertedNumber != nil {
@ -641,13 +632,13 @@ if let actualNumber = Int(possibleNumber) {
这段代码可以被理解为: 这段代码可以被理解为:
“如果`possibleNumber.toInt`返回的可选`Int`包含一个值,创建一个叫做`actualNumber`的新常量并将可选包含的值赋给它。” “如果`Int(possibleNumber)`返回的可选`Int`包含一个值,创建一个叫做`actualNumber`的新常量并将可选包含的值赋给它。”
如果转换成功,`actualNumber`常量可以在`if`语句的第一个分支中使用。它已经被可选类型_包含的_值初始化过所以不需要再使用`!`后缀来获取它的值。在这个例子中,`actualNumber`只被用来输出转换结果。 如果转换成功,`actualNumber`常量可以在`if`语句的第一个分支中使用。它已经被可选类型_包含的_值初始化过所以不需要再使用`!`后缀来获取它的值。在这个例子中,`actualNumber`只被用来输出转换结果。
你可以在可选绑定中使用常量和变量。如果你想在`if`语句的第一个分支中操作`actualNumber`的值,你可以改成`if var actualNumber`,这样可选类型包含的值就会被赋给一个变量而非常量。 你可以在可选绑定中使用常量和变量。如果你想在`if`语句的第一个分支中操作`actualNumber`的值,你可以改成`if var actualNumber`,这样可选类型包含的值就会被赋给一个变量而非常量。
多个可选绑定可以用逗号区分成一列表达式出现在一个`if`语句中。 多个可选绑定可以用逗号分隔,作为一列表达式出现在一个`if`语句中。
```swift ```swift
if let constantName = someOptional, anotherConstantName = someOtherOptional { if let constantName = someOptional, anotherConstantName = someOtherOptional {
@ -704,15 +695,15 @@ if let definiteString = assumedString {
<a name="error_handling"></a> <a name="error_handling"></a>
## 错误处理 ## 错误处理
你可以使用错误处理(error handling)来应对程序执行中出错的条件。 你可以使用错误处理(error handling)来应对程序执行中可能会遇到的错误条件。
相对于可选中运用值存在与缺失来表达函数的成功与失败,错误处理可以推断失败的原因,并传至程序的其他部分。 相对于可选中运用值存在与缺失来表达函数的成功与失败,错误处理可以推断失败的原因,并传至程序的其他部分。
当一个函数遇到错误条件,它能报错。调用函数的地方能抛出错误消息并合理处理。 当一个函数遇到错误条件,它能报错。调用函数的地方能抛出错误消息并合理处理。
```swift ```swift
func canThrowAnErrow() throws{ func canThrowAnErrow() throws {
//this function may or may not throw an error // 这个函数有可能抛出错误
} }
``` ```
@ -727,30 +718,30 @@ do {
} }
``` ```
一个`do`的声明创建了一个新的包含作用域,使得错误能被传播到一个或多`catch`从句。 一个`do`语句创建了一个新的包含作用域,使得错误能被传播到一个或多`catch`从句。
这里有一个错误处理用来应对不同错误条件的例子。 这里有一个错误处理如何用来应对不同错误条件的例子。
```swift ```swift
func makeASandwich() throws { func makeASandwich() throws {
// ... // ...
} }
do { do {
try makeASandwich() try makeASandwich()
eatASandwich() eatASandwich()
} catch Error.OutOfCleanDishes{ } catch Error.OutOfCleanDishes {
washDishes() washDishes()
} catch Error.MissingIngredients(let ingredients) { } catch Error.MissingIngredients(let ingredients) {
buyGroceries(ingredients) buyGroceries(ingredients)
} }
``` ```
在此例中,`makeASandwich()`(做一个三明治)函数会抛出一个错误消息如果没有干净的盘子或者某个原料缺失。因为`makeASandwich()`抛出错误,调用函数会被包裹在`try`表达式中。将函数包裹在一个`do`声明中,任何被抛出的错误会被传到提供的`catch`从句中。 在此例中,`makeASandwich()`(做一个三明治)函数会抛出一个错误消息如果没有干净的盘子或者某个原料缺失。因为`makeASandwich()`抛出错误,函数调用被包裹在`try`表达式中。将函数包裹在一个`do`语句中,任何被抛出的错误会被传到提供的`catch`从句中。
如果没有错误被抛出, `eatASandwich()`函数会被调用。如果一个符合`Error.OutOfCleanDishes`的错误被抛出,`washDishes`函数会被调用。如果一个符合`Error.MissingIngredients`的错误被抛出,`buyGroceries(_:)`函数会被调用并传递相关被`catch`所捕捉到的`[String]` 如果没有错误被抛出, `eatASandwich()`函数会被调用。如果一个匹配`Error.OutOfCleanDishes`的错误被抛出,`washDishes`函数会被调用。如果一个匹配`Error.MissingIngredients`的错误被抛出,`buyGroceries(_:)`函数会随着被`catch`所捕捉到的关联值`[String]`被调用
抛出,捕捉,传递错误会在[错误处理](./18_Error_Handling.html)章节详细说明。 抛出,捕捉,以及传播错误会在[错误处理](./18_Error_Handling.html)章节详细说明。
<a name="assertions"></a> <a name="assertions"></a>
## 断言 ## 断言
@ -759,11 +750,11 @@ do {
### 使用断言进行调试 ### 使用断言进行调试
断言会在运行时判断一个逻辑条件是否为`true`。从字面意思来说,断言“断言”一个条件是否为真。你可以使用断言来保证在运行其他代码之前,某些重要的条件已经被满足。如果条件判断为`true`,代码运行会继续进行;如果条件判断为`false`,代码运行停止,你的应用被终止。 断言会在运行时判断一个逻辑条件是否为`true`。从字面意思来说,断言“断言”一个条件是否为真。你可以使用断言来保证在运行其他代码之前,某些重要的条件已经被满足。如果条件判断为`true`,代码运行会继续进行;如果条件判断为`false`,代码执行结束,你的应用被终止。
如果你的代码在调试环境下触发了一个断言,比如你在 Xcode 中构建并运行一个应用,你可以清楚地看到不合法的状态发生在哪里并检查断言被触发时你的应用的状态。此外,断言允许你附加一条调试信息。 如果你的代码在调试环境下触发了一个断言,比如你在 Xcode 中构建并运行一个应用,你可以清楚地看到不合法的状态发生在哪里并检查断言被触发时你的应用的状态。此外,断言允许你附加一条调试信息。
你可以使用全局`assert`函数来写一个断言。向`assert`函数传入一个结果为`true`或者`false`的表达式以及一条信息,当表达式为`false`的时候这条信息会被显示: 你可以使用全局`assert(_:_:)`函数来写一个断言。向`assert(_:_:)`函数传入一个结果为`true`或者`false`的表达式以及一条信息,当表达式的结果为`false`的时候这条信息会被显示:
```swift ```swift
let age = -3 let age = -3
@ -771,9 +762,9 @@ assert(age >= 0, "A person's age cannot be less than zero")
// 因为 age < 0所以断言会触发 // 因为 age < 0所以断言会触发
``` ```
在这个例子中,只有`age >= 0`为`true`的时候,即`age`的值非负的时候,代码运行才会继续。如果`age`的值是负数,就像代码中那样,`age >= 0`为`false`,断言被触发,结束应用。 在这个例子中,只有`age >= 0`为`true`的时候,即`age`的值非负的时候,代码才会继续执行。如果`age`的值是负数,就像代码中那样,`age >= 0`为`false`,断言被触发,终止应用。
断言信息如果不需要,可以省略,就像这样: 如果不需要断言信息,可以省略,就像这样:
```swift ```swift
assert(age >= 0) assert(age >= 0)

View File

@ -44,22 +44,27 @@ Swift 支持大部分标准 C 语言的运算符,且改进许多特性来减
赋值运算(`a = b`),表示用`b`的值来初始化或更新`a`的值: 赋值运算(`a = b`),表示用`b`的值来初始化或更新`a`的值:
let b = 10 ```swift
var a = 5 let b = 10
a = b var a = 5
// a 现在等于 10 a = b
// a 现在等于 10
```
如果赋值的右边是一个多元组,它的元素可以马上被分解成多个常量或变量: 如果赋值的右边是一个多元组,它的元素可以马上被分解成多个常量或变量:
let (x, y) = (1, 2) ```swift
// 现在 x 等于 1, y 等于 2 let (x, y) = (1, 2)
// 现在 x 等于 1, y 等于 2
```
与 C 语言和 Objective-C 不同Swift 的赋值操作并不返回任何值。所以以下代码是错误的: 与 C 语言和 Objective-C 不同Swift 的赋值操作并不返回任何值。所以以下代码是错误的:
if x = y { ```swift
// 此句错误, 因为 x = y 并不返回任何值 if x = y {
} // 此句错误, 因为 x = y 并不返回任何值
}
```
这个特性使你无法把(`==`)错写成(`=`),由于`if x = y`是错误代码Swift帮你避免此类错误的的发生。 这个特性使你无法把(`==`)错写成(`=`),由于`if x = y`是错误代码Swift帮你避免此类错误的的发生。
@ -73,18 +78,20 @@ Swift 中所有数值类型都支持了基本的四则算术运算:
- 乘法(`*` - 乘法(`*`
- 除法(`/` - 除法(`/`
1 + 2 // 等于 3 ```swift
5 - 3 // 等于 2 1 + 2 // 等于 3
2 * 3 // 等于 6 5 - 3 // 等于 2
10.0 / 2.5 // 等于 4.0 2 * 3 // 等于 6
10.0 / 2.5 // 等于 4.0
```
与 C 语言和 Objective-C 不同的是Swift 默认情况下不允许在数值运算中出现溢出情况。但是你可以使用 Swift 的溢出运算符来实现溢出运算(如`a &+ b`)。详情参见[溢出运算符](./24_Advanced_Operators.html#overflow_operators)。 与 C 语言和 Objective-C 不同的是Swift 默认情况下不允许在数值运算中出现溢出情况。但是你可以使用 Swift 的溢出运算符来实现溢出运算(如`a &+ b`)。详情参见[溢出运算符](./24_Advanced_Operators.html#overflow_operators)。
加法运算符也可用于`String`的拼接: 加法运算符也可用于`String`的拼接:
"hello, " + "world" // 等于 "hello, world" ```swift
"hello, " + "world" // 等于 "hello, world"
```
### 求余运算符 ### 求余运算符
@ -101,8 +108,9 @@ Swift 中所有数值类型都支持了基本的四则算术运算:
在 Swift 中可以表达为: 在 Swift 中可以表达为:
9 % 4 // 等于 1 ```swift
9 % 4 // 等于 1
```
为了得到`a % b`的结果,`%`计算了以下等式,并输出`余数`作为结果: 为了得到`a % b`的结果,`%`计算了以下等式,并输出`余数`作为结果:
@ -114,10 +122,11 @@ Swift 中所有数值类型都支持了基本的四则算术运算:
9 = (4 × 2) + 1 9 = (4 × 2) + 1
同样的方法,我们来计算 `-9 % 4`
同样的方法,我来们计算 `-9 % 4` ```swift
-9 % 4 // 等于 -1
-9 % 4 // 等于 -1 ```
`-9``4`代入等式,`-2`是取到的最大整数: `-9``4`代入等式,`-2`是取到的最大整数:
@ -131,7 +140,9 @@ Swift 中所有数值类型都支持了基本的四则算术运算:
不同于 C 语言和 Objective-CSwift 中是可以对浮点数进行求余的。 不同于 C 语言和 Objective-CSwift 中是可以对浮点数进行求余的。
8 % 2.5 // 等于 0.5 ```swift
8 % 2.5 // 等于 0.5
```
这个例子中,`8`除于`2.5`等于`3``0.5`,所以结果是一个`Double``0.5` 这个例子中,`8`除于`2.5`等于`3``0.5`,所以结果是一个`Double``0.5`
@ -140,11 +151,11 @@ Swift 中所有数值类型都支持了基本的四则算术运算:
### 自增和自减运算 ### 自增和自减运算
和 C 语言一样Swift 也提供了对变量本身加1或减1的自增`++`)和自减(`--`)的缩略算符。其操作对象可以是整形和浮点型。 和 C 语言一样Swift 也提供了对变量本身加1或减1的自增`++`)和自减(`--`)的缩略算符。其操作对象可以是整形和浮点型。
var i = 0
++i // 现在 i = 1
```swift
var i = 0
++i // 现在 i = 1
```
每调用一次`++i``i`的值就会加1。实际上`++i``i = i + 1`的简写,而`--i``i = i - 1`的简写。 每调用一次`++i``i`的值就会加1。实际上`++i``i = i + 1`的简写,而`--i``i = i - 1`的简写。
@ -157,9 +168,11 @@ Swift 中所有数值类型都支持了基本的四则算术运算:
例如: 例如:
var a = 0 ```swift
let b = ++a // a 和 b 现在都是 1 var a = 0
let c = a++ // a 现在 2, 但 c 是 a 自增前的值 1 let b = ++a // a 和 b 现在都是 1
let c = a++ // a 现在 2, 但 c 是 a 自增前的值 1
```
上述例子,`let b = ++a`先把`a`加1了再返回`a`的值。所以`a``b`都是新值`1` 上述例子,`let b = ++a`先把`a`加1了再返回`a`的值。所以`a``b`都是新值`1`
@ -172,19 +185,22 @@ Swift 中所有数值类型都支持了基本的四则算术运算:
数值的正负号可以使用前缀`-`(即一元负号)来切换: 数值的正负号可以使用前缀`-`(即一元负号)来切换:
let three = 3 ```swift
let minusThree = -three // minusThree 等于 -3 let three = 3
let plusThree = -minusThree // plusThree 等于 3, 或 "负负3" let minusThree = -three // minusThree 等于 -3
let plusThree = -minusThree // plusThree 等于 3, 或 "负负3"
```
一元负号(`-`)写在操作数之前,中间没有空格。 一元负号(`-`)写在操作数之前,中间没有空格。
### 一元正号运算符 ### 一元正号运算符
一元正号(`+`)不做任何改变地返回操作数的值 一元正号(`+`)不做任何改变地返回操作数的值
let minusSix = -6 ```swift
let alsoMinusSix = +minusSix // alsoMinusSix 等于 -6 let minusSix = -6
let alsoMinusSix = +minusSix // alsoMinusSix 等于 -6
```
虽然一元`+`什么都不会改变,但当你在使用一元负号来表达负数时,你可以使用一元正号来表达正数,如此你的代码会具有对称美。 虽然一元`+`什么都不会改变,但当你在使用一元负号来表达负数时,你可以使用一元正号来表达正数,如此你的代码会具有对称美。
@ -194,9 +210,10 @@ Swift 中所有数值类型都支持了基本的四则算术运算:
如同 C 语言Swift 也提供把其他运算符和赋值运算(`=`)组合的复合赋值运算符,组合加运算(`+=`)是其中一个例子: 如同 C 语言Swift 也提供把其他运算符和赋值运算(`=`)组合的复合赋值运算符,组合加运算(`+=`)是其中一个例子:
var a = 1 ```swift
a += 2 // a 现在是 3 var a = 1
a += 2 // a 现在是 3
```
表达式`a += 2``a = a + 2`的简写,一个组合加运算就是把加法运算和赋值运算组合成进一个运算符里,同时完成两个运算任务。 表达式`a += 2``a = a + 2`的简写,一个组合加运算就是把加法运算和赋值运算组合成进一个运算符里,同时完成两个运算任务。
@ -208,7 +225,7 @@ Swift 中所有数值类型都支持了基本的四则算术运算:
<a name="comparison_operators"></a> <a name="comparison_operators"></a>
## 比较运算符 ## 比较运算符
所有标准 C 语言中的比较运算都可以在 Swift 中使用 所有标准 C 语言中的比较运算都可以在 Swift 中使用
- 等于(`a == b` - 等于(`a == b`
- 不等于(`a != b` - 不等于(`a != b`
@ -222,26 +239,26 @@ Swift 也提供恒等`===`和不恒等`!==`这两个比较符来判断两个对
每个比较运算都返回了一个标识表达式是否成立的布尔值: 每个比较运算都返回了一个标识表达式是否成立的布尔值:
```swift
1 == 1 // true, 因为 1 等于 1 1 == 1 // true, 因为 1 等于 1
2 != 1 // true, 因为 2 不等于 1 2 != 1 // true, 因为 2 不等于 1
2 > 1 // true, 因为 2 大于 1 2 > 1 // true, 因为 2 大于 1
1 < 2 // true, 因为 1 小于2 1 < 2 // true, 因为 1 小于2
1 >= 1 // true, 因为 1 大于等于 1 1 >= 1 // true, 因为 1 大于等于 1
2 <= 1 // false, 因为 2 并不小于等于 1 2 <= 1 // false, 因为 2 并不小于等于 1
```
比较运算多用于条件语句,如`if`条件: 比较运算多用于条件语句,如`if`条件:
```swift
let name = "world" let name = "world"
if name == "world" { if name == "world" {
print("hello, world") print("hello, world")
} else { } else {
print("I'm sorry \(name), but I don't recognize you") print("I'm sorry \(name), but I don't recognize you")
} }
// 输出 "hello, world", 因为 `name` 就是等于 "world" // 输出 "hello, world", 因为 `name` 就是等于 "world"
```
关于`if`语句,请看[控制流](./05_Control_Flow.html)。 关于`if`语句,请看[控制流](./05_Control_Flow.html)。
@ -252,32 +269,36 @@ Swift 也提供恒等`===`和不恒等`!==`这两个比较符来判断两个对
三目运算符是以下代码的缩写形式: 三目运算符是以下代码的缩写形式:
if question { ```swift
answer1 if question {
} else { answer1
answer2 } else {
} answer2
}
```
这里有个计算表格行高的例子。如果有表头那行高应比内容高度要高出50像素; 如果没有表头只需高出20像素。 这里有个计算表格行高的例子。如果有表头那行高应比内容高度要高出50点;如果没有表头只需高出20点:
let contentHeight = 40 ```swift
let hasHeader = true let contentHeight = 40
let rowHeight = contentHeight + (hasHeader ? 50 : 20) let hasHeader = true
// rowHeight 现在是 90 let rowHeight = contentHeight + (hasHeader ? 50 : 20)
// rowHeight 现在是 90
```
上面的写法比下面的代码更简洁:
这样写会比下面的代码简洁: ```swift
let contentHeight = 40
let contentHeight = 40 let hasHeader = true
let hasHeader = true var rowHeight = contentHeight
var rowHeight = contentHeight if hasHeader {
if hasHeader { rowHeight = rowHeight + 50
rowHeight = rowHeight + 50 } else {
} else { rowHeight = rowHeight + 20
rowHeight = rowHeight + 20 }
} // rowHeight 现在是 90
// rowHeight 现在是 90 ```
第一段代码例子使用了三目运算,所以一行代码就能让我们得到正确答案。这比第二段代码简洁得多,无需将`rowHeight`定义成变量,因为它的值无需在`if`语句中改变。 第一段代码例子使用了三目运算,所以一行代码就能让我们得到正确答案。这比第二段代码简洁得多,无需将`rowHeight`定义成变量,因为它的值无需在`if`语句中改变。
@ -293,7 +314,9 @@ Swift 也提供恒等`===`和不恒等`!==`这两个比较符来判断两个对
空合并运算符是对以下代码的简短表达方法 空合并运算符是对以下代码的简短表达方法
a != nil ? a! : b ```swift
a != nil ? a! : b
```
上述代码使用了三目运算符。当可选类型`a`的值不为空时,进行强制解封(`a!`)访问`a`中值,反之当`a`中值为空时返回默认值b。无疑空合运算符(`??`)提供了一种更为优雅的方式去封装条件判断和解封两种行为,显得简洁以及更具可读性。 上述代码使用了三目运算符。当可选类型`a`的值不为空时,进行强制解封(`a!`)访问`a`中值,反之当`a`中值为空时返回默认值b。无疑空合运算符(`??`)提供了一种更为优雅的方式去封装条件判断和解封两种行为,显得简洁以及更具可读性。
@ -302,21 +325,24 @@ Swift 也提供恒等`===`和不恒等`!==`这两个比较符来判断两个对
下文例子采用空合并运算符,实现了在默认颜色名和可选自定义颜色名之间抉择: 下文例子采用空合并运算符,实现了在默认颜色名和可选自定义颜色名之间抉择:
```swift
let defaultColorName = "red"
var userDefinedColorName: String? //默认值为 nil
let defaultColorName = "red" var colorNameToUse = userDefinedColorName ?? defaultColorName
var userDefinedColorName:String? //默认值为nil // userDefinedColorName 的值为空,所以 colorNameToUse 的值为 "red"
var colorNameToUse = userDefinedColorName ?? defaultColorName ```
//userDefinedColorName的值为空 所以colorNameToUse的值为`red`
`userDefinedColorName`变量被定义为一个可选`String`类型,默认值为`nil`。由于`userDefinedColorName`是一个可选类型,我们可以使用空合运算符去判断其值。在上一个例子中,通过空合运算符为一个名为`colorNameToUse`的变量赋予一个字符串类型初始值。 `userDefinedColorName`变量被定义为一个可选`String`类型,默认值为`nil`。由于`userDefinedColorName`是一个可选类型,我们可以使用空合运算符去判断其值。在上一个例子中,通过空合运算符为一个名为`colorNameToUse`的变量赋予一个字符串类型初始值。
由于`userDefinedColorName`值为空,因此表达式` userDefinedColorName ?? defaultColorName `返回`defaultColorName`的值,即`red` 由于`userDefinedColorName`值为空,因此表达式`userDefinedColorName ?? defaultColorName`返回`defaultColorName`的值,即`red`
另一种情况,分配一个非空值(`non-nil`)给 `userDefinedColorName`,再次执行空合运算,运算结果为封包在`userDefaultColorName`中的值,而非默认值。 另一种情况,分配一个非空值(`non-nil`)给`userDefinedColorName`,再次执行空合运算,运算结果为封包在`userDefaultColorName`中的值,而非默认值。
userDefinedColorName = "green" ```swift
colorNameToUse = userDefinedColorName ?? defaultColorName userDefinedColorName = "green"
//userDefinedColorName非空因此colorNameToUsede的值为绿色 colorNameToUse = userDefinedColorName ?? defaultColorName
// userDefinedColorName 非空,因此 colorNameToUse 的值为 "green"
```
<a name="range_operators"></a> <a name="range_operators"></a>
## 区间运算符 ## 区间运算符
@ -328,15 +354,16 @@ Swift 提供了两个方便表达一个区间的值的运算符。
闭区间运算符在迭代一个区间的所有值时是非常有用的,如在`for-in`循环中: 闭区间运算符在迭代一个区间的所有值时是非常有用的,如在`for-in`循环中:
for index in 1...5 { ```swift
print("\(index) * 5 = \(index * 5)") for index in 1...5 {
} print("\(index) * 5 = \(index * 5)")
// 1 * 5 = 5 }
// 2 * 5 = 10 // 1 * 5 = 5
// 3 * 5 = 15 // 2 * 5 = 10
// 4 * 5 = 20 // 3 * 5 = 15
// 5 * 5 = 25 // 4 * 5 = 20
// 5 * 5 = 25
```
关于`for-in`,请看[控制流](./05_Control_Flow.html)。 关于`for-in`,请看[控制流](./05_Control_Flow.html)。
@ -345,19 +372,19 @@ Swift 提供了两个方便表达一个区间的值的运算符。
半开区间(`a..<b`)定义一个从`a``b`但不包括`b`的区间。 半开区间(`a..<b`)定义一个从`a``b`但不包括`b`的区间。
之所以称为半开区间,是因为该区间包含第一个值而不包括最后的值。 之所以称为半开区间,是因为该区间包含第一个值而不包括最后的值。
半开区间的实用性在于当你使用一个0始的列表(如数组)时非常方便地从0数到列表的长度。 半开区间的实用性在于当你使用一个从0开始的列表(如数组)时非常方便地从0数到列表的长度。
let names = ["Anna", "Alex", "Brian", "Jack"]
let count = names.count
for i in 0..<count {
print(" \(i + 1) 个人叫 \(names[i])")
}
// 1 个人叫 Anna
// 2 个人叫 Alex
// 3 个人叫 Brian
// 4 个人叫 Jack
```swift
let names = ["Anna", "Alex", "Brian", "Jack"]
let count = names.count
for i in 0..<count {
print("第 \(i + 1) 个人叫 \(names[i])")
}
// 第 1 个人叫 Anna
// 第 2 个人叫 Alex
// 第 3 个人叫 Brian
// 第 4 个人叫 Jack
```
数组有4个元素`0..<count`只数到3(最后一个元素的下标),因为它是半开区间。关于数组,请查阅[数组](./04_Collection_Types.html#arrays)。 数组有4个元素`0..<count`只数到3(最后一个元素的下标),因为它是半开区间。关于数组,请查阅[数组](./04_Collection_Types.html#arrays)。
@ -376,14 +403,15 @@ Swift 提供了两个方便表达一个区间的值的运算符。
它是一个前置运算符,需紧跟在操作数之前,且不加空格。读作`非 a`,例子如下: 它是一个前置运算符,需紧跟在操作数之前,且不加空格。读作`非 a`,例子如下:
let allowedEntry = false ```swift
if !allowedEntry { let allowedEntry = false
print("ACCESS DENIED") if !allowedEntry {
} print("ACCESS DENIED")
// 输出 "ACCESS DENIED" }
// 输出 "ACCESS DENIED"
```
`if !allowedEntry`语句可以读作“如果非 allowedEntry。”接下一行代码只有在“非 allowedEntry”为`true`,即`allowEntry``false`时被执行。
`if !allowedEntry`语句可以读作 "如果 非 alowed entry。",接下一行代码只有在如果 "非 allow entry" 为`true`,即`allowEntry``false`时被执行。
在示例代码中,小心地选择布尔常量或变量有助于代码的可读性,并且避免使用双重逻辑非运算,或混乱的逻辑语句。 在示例代码中,小心地选择布尔常量或变量有助于代码的可读性,并且避免使用双重逻辑非运算,或混乱的逻辑语句。
@ -391,51 +419,56 @@ Swift 提供了两个方便表达一个区间的值的运算符。
逻辑与(`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`的时候才允许进入: 以下例子,只有两个`Bool`值都为`true`的时候才允许进入:
let enteredDoorCode = true ```swift
let passedRetinaScan = false let enteredDoorCode = true
if enteredDoorCode && passedRetinaScan { let passedRetinaScan = false
print("Welcome!") if enteredDoorCode && passedRetinaScan {
} else { print("Welcome!")
print("ACCESS DENIED") } else {
} print("ACCESS DENIED")
// 输出 "ACCESS DENIED" }
// 输出 "ACCESS DENIED"
```
### 逻辑或 ### 逻辑或
逻辑或(`a || b`)是一个由两个连续的`|`组成的中置运算符。它表示了两个逻辑表达式的其中一个为`true`,整个表达式就为`true` 逻辑或(`a || b`)是一个由两个连续的`|`组成的中置运算符。它表示了两个逻辑表达式的其中一个为`true`,整个表达式就为`true`
同逻辑与运算类似,逻辑或也是"短路计算"的,当左端的表达式为`true`时,将不计算右边的表达式了,因为它不可能改变整个表达式的值了。 同逻辑与运算类似,逻辑或也是短路计算的,当左端的表达式为`true`时,将不计算右边的表达式了,因为它不可能改变整个表达式的值了。
以下示例代码中,第一个布尔值(`hasDoorKey`)为`false`,但第二个值(`knowsOverridePassword`)为`true`,所以整个表达是`true`,于是允许进入: 以下示例代码中,第一个布尔值(`hasDoorKey`)为`false`,但第二个值(`knowsOverridePassword`)为`true`,所以整个表达是`true`,于是允许进入:
let hasDoorKey = false ```swift
let knowsOverridePassword = true let hasDoorKey = false
if hasDoorKey || knowsOverridePassword { let knowsOverridePassword = true
print("Welcome!") if hasDoorKey || knowsOverridePassword {
} else { print("Welcome!")
print("ACCESS DENIED") } else {
} print("ACCESS DENIED")
// 输出 "Welcome!" }
// 输出 "Welcome!"
```
### 逻辑运算符组合计算 ### 逻辑运算符组合计算
我们可以组合多个逻辑运算来表达一个复合逻辑: 我们可以组合多个逻辑运算来表达一个复合逻辑:
if enteredDoorCode && passedRetinaScan || hasDoorKey || knowsOverridePassword { ```swift
print("Welcome!") if enteredDoorCode && passedRetinaScan || hasDoorKey || knowsOverridePassword {
} else { print("Welcome!")
print("ACCESS DENIED") } else {
} print("ACCESS DENIED")
// 输出 "Welcome!" }
// 输出 "Welcome!"
```
这个例子使用了含多个`&&``||`的复合逻辑。但无论怎样,`&&``||`始终只能操作两个值。所以这实际是三个简单逻辑连续操作的结果。我们来解读一下: 这个例子使用了含多个`&&``||`的复合逻辑。但无论怎样,`&&``||`始终只能操作两个值。所以这实际是三个简单逻辑连续操作的结果。我们来解读一下:
如果我们输入了正确的密码并通过了视网膜扫描; 或者我们有一把有效的钥匙; 又或者我们知道紧急情况下重置的密码,我们就能把门打开进入。 如果我们输入了正确的密码并通过了视网膜扫描或者我们有一把有效的钥匙又或者我们知道紧急情况下重置的密码,我们就能把门打开进入。
前两种情况,我们都不满足,所以前两个简单逻辑的结果是`false`,但是我们是知道紧急情况下重置的密码的,所以整个复杂表达式的值还是`true` 前两种情况,我们都不满足,所以前两个简单逻辑的结果是`false`,但是我们是知道紧急情况下重置的密码的,所以整个复杂表达式的值还是`true`
@ -444,15 +477,15 @@ Swift 逻辑操作符`&&`和`||`是左结合的,这意味着拥有多元逻辑
### 使用括号来明确优先级 ### 使用括号来明确优先级
为了一个复杂表达式更容易读懂,在合适的地方使用括号来明确优先级是很有效的,虽然它并非必要的。在上个关于门的权限的例子中,我们给第一个部分加个括号,使它看起来逻辑更明确: 为了一个复杂表达式更容易读懂,在合适的地方使用括号来明确优先级是很有效的,虽然它并非必要的。在上个关于门的权限的例子中,我们给第一个部分加个括号,使它看起来逻辑更明确:
```swift
if (enteredDoorCode && passedRetinaScan) || hasDoorKey || knowsOverridePassword {
print("Welcome!")
} else {
print("ACCESS DENIED")
}
// 输出 "Welcome!"
```
if (enteredDoorCode && passedRetinaScan) || hasDoorKey || knowsOverridePassword { 这括号使得前两个值被看成整个逻辑表达中独立的一个部分。虽然有括号和没括号的输出结果是一样的,但对于读代码的人来说有括号的代码更清晰。可读性比简洁性更重要,请在可以让你代码变清晰的地方加个括号吧!
print("Welcome!")
} else {
print("ACCESS DENIED")
}
// 输出 "Welcome!"
这括号使得前两个值被看成整个逻辑表达中独立的一个部分。虽然有括号和没括号的输出结果是一样的,但对于读代码的人来说有括号的代码更清晰。可读性比简洁性更重要,请在可以让你代码变清晰地地方加个括号吧!

View File

@ -292,7 +292,7 @@ someFunction(1, 2)
> 注意: > 注意:
> 因为第一个参数默认忽略其外部参数名称,明确写下划线是多余的。 > 因为第一个参数默认忽略其外部参数名称,明确写下划线是多余的。
<a name="default_parameter_values"></a>
### 默认参数值Default Parameter Values ### 默认参数值Default Parameter Values
你可以在函数体中为每个参数定义`默认值(Deafult Values)`。当默认值被定义后,调用这个函数时可以忽略这个参数。 你可以在函数体中为每个参数定义`默认值(Deafult Values)`。当默认值被定义后,调用这个函数时可以忽略这个参数。