This commit is contained in:
wuxing
2014-06-14 15:49:19 +08:00
parent b3ef454499
commit 9547fd69fe
115 changed files with 73 additions and 73 deletions

BIN
source/.DS_Store vendored Normal file

Binary file not shown.

0
source/README.md Normal file → Executable file
View File

0
source/SUMMARY.md Normal file → Executable file
View File

6
source/chapter1/01_swift.md Normal file → Executable file
View File

@ -5,9 +5,9 @@
# 关于 Swift
-----------------
Swift 是一种新的编程语言,用于编写 iOS 和 OS X 应用。Swift 结合了 C 和 Objective-C 的优点并且不受C兼容性的限制。Swift 采用安全的编程模式并添加了很多新特性这将使编程更简单更灵活也更有趣。Swift 是基于成熟而且倍受喜爱的 Cocoa 和 Cocoa Touch 框架,他的降临将重新定义软件开发。
Swift 是一种新的编程语言,用于编写 iOS 和 OS X 应用。Swift 结合了 C 和 Objective-C 的优点并且不受 C 兼容性的限制。Swift 采用安全的编程模式并添加了很多新特性这将使编程更简单更灵活也更有趣。Swift 是基于成熟而且倍受喜爱的 Cocoa 和 Cocoa Touch 框架,他的降临将重新定义软件开发。
Swift 的开发从很久之前就开始了。为了给 Swift 打好基础苹果公司改进了编译器调试器和框架结构。我们使用自动引用计数Automatic Reference Counting, ARC来简化内存管理。我们在 Foundation 和 Cocoa的基础上构建框架栈并将其标准化。Objective-C 本身支持块、集合语法和模块,所以框架可以轻松支持现代编程语言技术。正是得益于这些基础工作,我们现在才能发布这样一个用于未来苹果软件开发的新语言。
Swift 的开发从很久之前就开始了。为了给 Swift 打好基础苹果公司改进了编译器调试器和框架结构。我们使用自动引用计数Automatic Reference Counting, ARC来简化内存管理。我们在 Foundation 和 Cocoa 的基础上构建框架栈并将其标准化。Objective-C 本身支持块、集合语法和模块,所以框架可以轻松支持现代编程语言技术。正是得益于这些基础工作,我们现在才能发布这样一个用于未来苹果软件开发的新语言。
Objective-C 开发者对 Swift 并不会感到陌生。它采用了 Objective-C 的命名参数以及动态对象模型,可以无缝对接到现有的 Cocoa 框架,并且可以兼容 Objective-C 代码。在此基础之上Swift 还有许多新特性并且支持过程式编程和面向对象编程。
@ -15,4 +15,4 @@ Swift 对于初学者来说也很友好。它是第一个既满足工业标准
Swift 将现代编程语言的精华和苹果工程师文化的智慧结合了起来。编译器对性能进行了优化编程语言对开发进行了优化两者互不干扰鱼与熊掌兼得。Swift 既可以用于开发 “hello, world” 这样的小程序,也可以用于开发一套完整的操作系统。所有的这些特性让 Swift 对于开发者和苹果来说都是一项值得的投资。
Swift 编写 iOS 和 OS X 应用将是一场美妙的体验Swift 之后也会不断开发新特性和兼容性。我们对 Swift 充满信心,你还在等什么!
Swift 编写 iOS 和 OS X 应用的极佳手段,并将伴随着新的特性和功能持续演进。我们对 Swift 充满信心,你还在等什么!

8
source/chapter1/02_a_swift_tour.md Normal file → Executable file
View File

@ -32,7 +32,7 @@
<a name="simple_values"></a>
## 简单值
使用`let`来声明常量,使用`var`来声明变量。一个常量的值在编译时并不需要获取,但是你只能为它赋值一次。也就是说你可以用常量来表示这样一个值:你只需要决定一次,但是需要使用很多次。
使用`let`来声明常量,使用`var`来声明变量。一个常量的值在编译的时候,并不需要有明确的值,但是你只能为它赋值一次。也就是说你可以用常量来表示这样一个值:你只需要决定一次,但是需要使用很多次。
```swift
var myVariable = 42
@ -455,7 +455,7 @@
2. 调用父类的构造器
3. 改变父类定义的属性值。其他的工作比如调用方法、getters和setters也可以在这个阶段完成。
如果你不需要计算属性但是需要在设置一个新值之前运行一些代码,使用`willSet``didSet`
如果你不需要计算属性但是仍然需要在设置一个新值之前或者之后运行代码,使用`willSet``didSet`
比如,下面的类确保三角形的边长总是和正方形的边长相同。
@ -665,7 +665,7 @@
注意声明`SimpleStructure`时候`mutating`关键字用来标记一个会修改结构体的方法。`SimpleClass`的声明不需要标记任何方法因为类中的方法经常会修改类。
使用`extension`来为现有的类型添加功能,比如添加一个计算属性的方法。你可以使用扩展来给任意类型添加协议,甚至是从外部库或者框架中导入的类型
使用`extension`来为现有的类型添加功能,比如新的方法和参数。你可以使用扩展来改造定义在别处,甚至是从外部库或者框架引入的一个类型,使得这个类型遵循某个协议
```swift
extension Int: ExampleProtocol {
@ -721,7 +721,7 @@
possibleInteger = .Some(100)
```
在类型名后面使用`where`来指定一个需求列表——例如,限定实现一个协议的类型,需要限定两个类型相同,或者限定个类必须有一个特定的父类
在类型名后面使用`where`来指定对类型的需求,比如,限定类型实现一个协议限定两个类型相同,或者限定个类必须有一个特定的父类
```swift
func anyCommonElements <T, U where T: Sequence, U: Sequence, T.GeneratorType.Element: Equatable, T.GeneratorType.Element == U.GeneratorType.Element> (lhs: T, rhs: U) -> Bool {

0
source/chapter1/chapter1.md Normal file → Executable file
View File

92
source/chapter2/01_The_Basics.md Normal file → Executable file
View File

@ -12,7 +12,7 @@
- [分号](#semicolons)
- [整数](#integers)
- [浮点数](#floating-point_numbers)
- [类型安全和类型推](#type_safety_and_type_inference)
- [类型安全和类型推](#type_safety_and_type_inference)
- [数值型字面量](#numeric_literals)
- [数值型类型转换](#numeric_type_conversion)
- [类型别名](#type_aliases)
@ -195,7 +195,7 @@ Swift 也提供了一个特殊的无符号类型`UInt`,长度与当前平台
> 注意:
>
尽量不要使用`UInt`,除非你真的需要存储一个和当前平台原生字长相同的无符号整数。除了这种情况,最好使用`Int`,即使你要存储的值已知是非负的。统一使用`Int`可以提高代码的可复用性,避免不同类型数字之间的转换,并且匹配数字的类型推,请参考[类型安全和类型推](#type_safety_and_type_inference)。
尽量不要使用`UInt`,除非你真的需要存储一个和当前平台原生字长相同的无符号整数。除了这种情况,最好使用`Int`,即使你要存储的值已知是非负的。统一使用`Int`可以提高代码的可复用性,避免不同类型数字之间的转换,并且匹配数字的类型推,请参考[类型安全和类型推](#type_safety_and_type_inference)。
<a name="floating-point_numbers"></a>
## 浮点数
@ -212,36 +212,36 @@ Swift 也提供了一个特殊的无符号类型`UInt`,长度与当前平台
`Double`精确度很高至少有15位数字而`Float`最少只有6位数字。选择哪个类型取决于你的代码需要处理的值的范围。
<a name="type_safety_and_type_inference"></a>
## 类型安全和类型推
## 类型安全和类型推
Swift 是一个_类型安全type safe_的语言。类型安全的语言可以让你清楚地知道代码要处理的值的类型。如果你的代码需要一个`String`,你绝对不可能不小心传进去一个`Int`
由于 Swift 是类型安全的所以它会在编译你的代码时进行_类型检查type checks_并把不匹配的类型标记为错误。这可以让你在开发的时候尽早发现并修复错误。
当你要处理不同类型的值时类型检查可以帮你避免错误。然而这并不是说你每次声明常量和变量的时候都需要显式指定类型。如果你没有显式指定类型Swift 会使用_类型推type inference_来选择合适的类型。有了类型推,编译器可以在编译代码的时候自动推出表达式的类型。原理很简单,只要检查你赋的值即可。
当你要处理不同类型的值时类型检查可以帮你避免错误。然而这并不是说你每次声明常量和变量的时候都需要显式指定类型。如果你没有显式指定类型Swift 会使用_类型推type inference_来选择合适的类型。有了类型推,编译器可以在编译代码的时候自动推出表达式的类型。原理很简单,只要检查你赋的值即可。
因为有类型推,和 C 或者 Objective-C 比起来 Swift 很少需要声明类型。常量和变量虽然需要明确类型,但是大部分工作并不需要你自己来完成。
因为有类型推,和 C 或者 Objective-C 比起来 Swift 很少需要声明类型。常量和变量虽然需要明确类型,但是大部分工作并不需要你自己来完成。
当你声明常量或者变量并赋初值的时候类型推非常有用。当你在声明常量或者变量的时候赋给它们一个_字面量literal value 或 literal_即可触发类型推。(字面量就是会直接出现在你代码中的值,比如`42``3.14159`。)
当你声明常量或者变量并赋初值的时候类型推非常有用。当你在声明常量或者变量的时候赋给它们一个_字面量literal value 或 literal_即可触发类型推。(字面量就是会直接出现在你代码中的值,比如`42``3.14159`。)
例如,如果你给一个新常量赋值`42`并且没有标明类型Swift 可以推出常量类型是`Int`,因为你给它赋的初始值看起来像一个整数:
例如,如果你给一个新常量赋值`42`并且没有标明类型Swift 可以推出常量类型是`Int`,因为你给它赋的初始值看起来像一个整数:
let meaningOfLife = 42
// meaningOfLife 会被推为 Int 类型
// meaningOfLife 会被推为 Int 类型
同理如果你没有给浮点字面量标明类型Swift 会推你想要的是`Double`
同理如果你没有给浮点字面量标明类型Swift 会推你想要的是`Double`
let pi = 3.14159
// pi 会被推为 Double 类型
// pi 会被推为 Double 类型
当推浮点数的类型时Swift 总是会选择`Double`而不是`Float`
当推浮点数的类型时Swift 总是会选择`Double`而不是`Float`
如果表达式中同时出现了整数和浮点数,会被推`Double`类型:
如果表达式中同时出现了整数和浮点数,会被推`Double`类型:
let anotherPi = 3 + 0.14159
// anotherPi 会被推为 Double 类型
// anotherPi 会被推为 Double 类型
原始值`3`没有显式声明类型,而表达式中出现了一个浮点字面量,所以表达式会被推`Double`类型。
原始值`3`没有显式声明类型,而表达式中出现了一个浮点字面量,所以表达式会被推`Double`类型。
<a name="numeric_literals"></a>
## 数值型字面量
@ -285,7 +285,7 @@ Swift 是一个_类型安全type safe_的语言。类型安全的语言可
<a name="numeric_type_conversion"></a>
## 数值型类型转换
通常来讲,即使代码中的整数常量和变量已知非负,也请使用`Int`类型。总是使用默认的整数类型可以保证你的整数常量和变量可以直接被复用并且可以匹配整数类字面量的类型推
通常来讲,即使代码中的整数常量和变量已知非负,也请使用`Int`类型。总是使用默认的整数类型可以保证你的整数常量和变量可以直接被复用并且可以匹配整数类字面量的类型推
只有在必要的时候才使用其他整数类型,比如要处理外部的长度明确的数据或者为了优化性能、内存占用等等。使用显式指定长度的类型可以及时发现值溢出并且可以暗示正在处理特殊数据。
### 整数转换
@ -305,7 +305,7 @@ Swift 是一个_类型安全type safe_的语言。类型安全的语言可
let one: UInt8 = 1
let twoThousandAndOne = twoThousand + UInt16(one)
现在两个数字的类型都是`UInt16`,可以进行相加。目标常量`twoThousandAndOne`的类型被推`UInt16`,因为它是两个`UInt16`值的和。
现在两个数字的类型都是`UInt16`,可以进行相加。目标常量`twoThousandAndOne`的类型被推`UInt16`,因为它是两个`UInt16`值的和。
`SomeType(ofInitialValue)`是调用 Swift 构造器并传入一个初始值的默认方法。在语言内部,`UInt16`有一个构造器,可以接受一个`UInt8`类型的值,所以这个构造器可以用现有的`UInt8`来创建一个新的`UInt16`。注意,你并不能传入任意类型的值,只能传入`UInt16`内部有对应构造器的值。不过你可以扩展现有的类型来让它可以接收其他类型的值(包括自定义类型),请参考[扩展](20_Extensions.html)。
@ -316,20 +316,20 @@ Swift 是一个_类型安全type safe_的语言。类型安全的语言可
let three = 3
let pointOneFourOneFiveNine = 0.14159
let pi = Double(three) + pointOneFourOneFiveNine
// pi 等于 3.14159,所以被推为 Double 类型
// pi 等于 3.14159,所以被推为 Double 类型
这个例子中,常量`three`的值被用来创建一个`Double`类型的值,所以加号两边的数类型相同。如果不进行转换,两者无法相加。
这个例子中,常量`three`的值被用来创建一个`Double`类型的值,所以加号两边的数类型相同。如果不进行转换,两者无法相加。
浮点数到整数的反向转换同样行,整数类型可以用`Double`或者`Float`类型来初始化:
let integerPi = Int(pi)
// integerPi 等于 3所以被推为 Int 类型
// integerPi 等于 3所以被推为 Int 类型
当用这种方式来初始化一个新的整数值时,浮点值会被截断。也就是说`4.75`会变成`4``-3.9`会变成`-3`
> 注意:
>
结合数字类常量和变量不同于结合数字类字面量。字面量`3`可以直接和字面量`0.14159`相加,因为数字字面量本身没有明确的类型。它们的类型只在编译器需要求值的时候被推
结合数字类常量和变量不同于结合数字类字面量。字面量`3`可以直接和字面量`0.14159`相加,因为数字字面量本身没有明确的类型。它们的类型只在编译器需要求值的时候被推断出来
<a name="type_aliases"></a>
## 类型别名
@ -355,7 +355,7 @@ Swift 有一个基本的_布尔Boolean_类型叫做`Bool`。布尔值
let orangesAreOrange = true
let turnipsAreDelicious = false
`orangesAreOrange``turnipsAreDelicious`的类型会被推`Bool`,因为它们的初值是布尔字面量。就像之前提到的`Int``Double`一样,如果你创建变量的时候给它们赋值`true`或者`false`,那你不需要将常量或者变量声明为`Bool`类型。初始化常量或者变量的时候如果所赋的值类型已知,就可以触发类型推,这让 Swift 代码更加简洁并且可读性更高。
`orangesAreOrange``turnipsAreDelicious`的类型会被推`Bool`,因为它们的初值是布尔字面量。就像之前提到的`Int``Double`一样,如果你创建变量的时候给它们赋值`true`或者`false`,那你不需要将常量或者变量声明为`Bool`类型。初始化常量或者变量的时候如果所赋的值类型已知,就可以触发类型推,这让 Swift 代码更加简洁并且可读性更高。
当你编写条件语句比如`if`语句的时候,布尔值非常有用:
@ -439,9 +439,9 @@ _元组tuples_把多个值组合成一个复合值。元组内的值可以
元组在临时组织值的时候很有用,但是并不适合创建复杂的数据结构。如果你的数据结构并不是临时使用,请使用类或者结构体而不是元组。请参考[类和结构体](09_Classes_and_Structures.html)。
<a name="optionals"></a>
## 可选
## 可选类型
使用_可选optionals_来处理值可能缺失的情况。可选表示
使用_可选类型optionals_来处理值可能缺失的情况。可选类型表示:
* _有_值等于 x
@ -451,7 +451,7 @@ _元组tuples_把多个值组合成一个复合值。元组内的值可以
> 注意:
>
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"`不行。
@ -459,15 +459,15 @@ C 和 Objective-C 中并没有可选这个概念。最接近的是 Objective-C
let possibleNumber = "123"
let convertedNumber = possibleNumber.toInt()
// convertedNumber 被推为类型 "Int?" 或者类型 "optional Int"
// convertedNumber 被推为类型 "Int?" 或者类型 "optional Int"
因为`toInt`方法可能会失败所以它返回一个_可选optional_`Int`,而不是一个`Int`。一个可选的`Int`被写作`Int?`而不是`Int`。问号暗示包含的值是可选,也就是说可能包含`Int`值也可能不包含值。(不能包含其他任何值比如`Bool`值或者`String`值。只能是`Int`或者什么都没有。)
因为`toInt`方法可能会失败所以它返回一个_可选类型optional_`Int`,而不是一个`Int`。一个可选的`Int`被写作`Int?`而不是`Int`。问号暗示包含的值是可选类型,也就是说可能包含`Int`值也可能不包含值。(不能包含其他任何值比如`Bool`值或者`String`值。只能是`Int`或者什么都没有。)
### if 语句以及强制解析
你可以使用`if`语句来判断一个可选是否包含值。如果可选有值,结果是`true`;如果没有值,结果是`false`
你可以使用`if`语句来判断一个可选是否包含值。如果可选类型有值,结果是`true`;如果没有值,结果是`false`
当你确定可选_确实_包含值之后你可以在可选的名字后面加一个感叹号`!`来获取值。这个惊叹号表示“我知道这个可选有值请使用它。”这被称为可选值的_强制解析forced unwrapping_
当你确定可选类型_确实_包含值之后你可以在可选的名字后面加一个感叹号`!`来获取值。这个惊叹号表示“我知道这个可选有值请使用它。”这被称为可选值的_强制解析forced unwrapping_
if convertedNumber {
println("\(possibleNumber) has an integer value of \(convertedNumber!)")
@ -485,7 +485,7 @@ C 和 Objective-C 中并没有可选这个概念。最接近的是 Objective-C
<a name="optional_binding"></a>
### 可选绑定
使用_可选绑定optional binding_来判断可选是否包含值如果包含就把值赋给一个临时常量或者变量。可选绑定可以用在`if``while`语句中来对可选的值进行判断并把值赋给一个常量或者变量。`if``while`语句,请参考[控制流](05_Control_Flow.html)。
使用_可选绑定optional binding_来判断可选类型是否包含值,如果包含就把值赋给一个临时常量或者变量。可选绑定可以用在`if``while`语句中来对可选类型的值进行判断并把值赋给一个常量或者变量。`if``while`语句,请参考[控制流](05_Control_Flow.html)。
像下面这样在`if`语句中写一个可选绑定:
@ -506,9 +506,9 @@ C 和 Objective-C 中并没有可选这个概念。最接近的是 Objective-C
“如果`possibleNumber.toInt`返回的可选`Int`包含一个值,创建一个叫做`actualNumber`的新常量并将可选包含的值赋给它。”
如果转换成功,`actualNumber`常量可以在`if`语句的第一个分支中使用。它已经被可选_包含的_值初始化过所以不需要再使用`!`后缀来获取它的值。在这个例子中,`actualNumber`只被用来输出转换结果。
如果转换成功,`actualNumber`常量可以在`if`语句的第一个分支中使用。它已经被可选类型_包含的_值初始化过所以不需要再使用`!`后缀来获取它的值。在这个例子中,`actualNumber`只被用来输出转换结果。
你可以在可选绑定中使用常量和变量。如果你想在`if`语句的第一个分支中操作`actualNumber`的值,你可以改成`if var actualNumber`,这样可选包含的值就会被赋给一个变量而非常量。
你可以在可选绑定中使用常量和变量。如果你想在`if`语句的第一个分支中操作`actualNumber`的值,你可以改成`if var actualNumber`,这样可选类型包含的值就会被赋给一个变量而非常量。
### nil
@ -530,19 +530,19 @@ C 和 Objective-C 中并没有可选这个概念。最接近的是 Objective-C
> 注意:
>
Swift 的`nil`和 Objective-C 中的`nil`并不一样。在 Objective-C 中,`nil`是一个指向不存在对象的指针。在 Swift 中,`nil`不是指针——它是一个确定的值用来表示值缺失。_任何_类型的可选都可以被设置为`nil`,不只是对象类型。
Swift 的`nil`和 Objective-C 中的`nil`并不一样。在 Objective-C 中,`nil`是一个指向不存在对象的指针。在 Swift 中,`nil`不是指针——它是一个确定的值用来表示值缺失。_任何_类型的可选状态都可以被设置为`nil`,不只是对象类型。
### 隐式解析可选
### 隐式解析可选类型
如上所述,可选暗示了常量或者变量可以“没有值”。可选可以通过`if`语句来判断是否有值,如果有值的话可以通过可选绑定来解析值。
如上所述,可选类型暗示了常量或者变量可以“没有值”。可选可以通过`if`语句来判断是否有值,如果有值的话可以通过可选绑定来解析值。
有时候在程序架构中第一次被赋值之后可以确定一个可选_总会_有值。在这种情况下每次都要判断和解析可选值是非常低效的因为可以确定它总会有值。
有时候在程序架构中,第一次被赋值之后,可以确定一个可选类型_总会_有值。在这种情况下每次都要判断和解析可选值是非常低效的因为可以确定它总会有值。
这种类型的可选被定义为_隐式解析可选implicitly unwrapped optionals_。把想要用作可选的类型的后面的问号`String?`)改成感叹号(`String!`)来声明一个隐式解析可选。
这种类型的可选状态被定义为_隐式解析可选类型implicitly unwrapped optionals_。把想要用作可选的类型的后面的问号`String?`)改成感叹号(`String!`)来声明一个隐式解析可选类型
当可选被第一次赋值之后就可以确定之后一直有值的时候,隐式解析可选非常有用。隐式解析可选主要被用在 Swift 中类的构造过程中,请参考[类实例之间的循环强引用](16_Automatic_Reference_Counting.html#strong_reference_cycles_between_class_instances)。
当可选类型被第一次赋值之后就可以确定之后一直有值的时候,隐式解析可选类型非常有用。隐式解析可选类型主要被用在 Swift 中类的构造过程中,请参考[类实例之间的循环强引用](16_Automatic_Reference_Counting.html#strong_reference_cycles_between_class_instances)。
一个隐式解析可选其实就是一个普通的可选,但是可以被当做非可选来使用,并不需要每次都使用解析来获取可选值。下面的例子展示了可选`String`和隐式解析可选`String`之间的区别:
一个隐式解析可选类型其实就是一个普通的可选类型,但是可以被当做非可选类型来使用,并不需要每次都使用解析来获取可选值。下面的例子展示了可选类型`String`和隐式解析可选类型`String`之间的区别:
let possibleString: String? = "An optional string."
println(possibleString!) // 需要惊叹号来获取值
@ -552,20 +552,20 @@ Swift 的`nil`和 Objective-C 中的`nil`并不一样。在 Objective-C 中,`n
println(assumedString) // 不需要感叹号
// 输出 "An implicitly unwrapped optional string."
你可以把隐式解析可选当做一个可以自动解析的可选。你要做的只是声明的时候把感叹号放到类型的结尾,而不是每次取值的可选名字的结尾。
你可以把隐式解析可选类型当做一个可以自动解析的可选类型。你要做的只是声明的时候把感叹号放到类型的结尾,而不是每次取值的可选名字的结尾。
> 注意:
>
如果你在隐式解析可选没有值的时候尝试取值,会触发运行时错误。和你在没有值的普通可选后面加一个惊叹号一样。
如果你在隐式解析可选类型没有值的时候尝试取值,会触发运行时错误。和你在没有值的普通可选类型后面加一个惊叹号一样。
你仍然可以把隐式解析可选当做普通可选来判断它是否包含值:
你仍然可以把隐式解析可选类型当做普通可选类型来判断它是否包含值:
if assumedString {
println(assumedString)
}
// 输出 "An implicitly unwrapped optional string."
你也可以在可选绑定中使用隐式解析可选来检查并解析它的值:
你也可以在可选绑定中使用隐式解析可选类型来检查并解析它的值:
if let definiteString = assumedString {
println(definiteString)
@ -574,12 +574,12 @@ Swift 的`nil`和 Objective-C 中的`nil`并不一样。在 Objective-C 中,`n
> 注意:
>
如果一个变量之后可能变成`nil`的话请不要使用隐式解析可选。如果你需要在变量的生命周期中判断是否是`nil`的话,请使用普通可选类型。
如果一个变量之后可能变成`nil`的话请不要使用隐式解析可选类型。如果你需要在变量的生命周期中判断是否是`nil`的话,请使用普通可选类型。
<a name="assertions"></a>
## 断言
可选可以让你判断值是否存在你可以在代码中优雅地处理值缺失的情况。然而在某些情况下如果值缺失或者值并不满足特定的条件你的代码可能并不需要继续执行。这时你可以在你的代码中触发一个_断言assertion_来结束代码运行并通过调试来找到值缺失的原因。
可选类型可以让你判断值是否存在你可以在代码中优雅地处理值缺失的情况。然而在某些情况下如果值缺失或者值并不满足特定的条件你的代码可能并不需要继续执行。这时你可以在你的代码中触发一个_断言assertion_来结束代码运行并通过调试来找到值缺失的原因。
### 使用断言进行调试
@ -603,11 +603,11 @@ Swift 的`nil`和 Objective-C 中的`nil`并不一样。在 Objective-C 中,`n
当条件可能为假时使用断言但是最终一定要_保证_条件为真这样你的代码才能继续运行。断言的适用情景
* 整数的附属脚本索引被传入一个自定义附属脚本实现,但是下标索引值可能太小或者太大。
* 整数类型的下标索引被传入一个自定义下标脚本实现,但是下标索引值可能太小或者太大。
* 需要给函数传入一个值,但是非法的值可能导致函数不能正常执行。
* 一个可选值现在是`nil`,但是后面的代码运行需要一个非`nil`值。
请参考[附属脚本](12_Subscripts.html)和[函数](06_Functions.html)。
请参考[下标脚本](12_Subscripts.html)和[函数](06_Functions.html)。
> 注意:
>

0
source/chapter2/02_Basic_Operators.md Normal file → Executable file
View File

0
source/chapter2/03_Strings_and_Characters.md Normal file → Executable file
View File

38
source/chapter2/04_Collection_Types.md Normal file → Executable file
View File

@ -24,7 +24,7 @@ Swift 的数组结构在被声明成常量和变量或者被传入函数与方
数组使用有序列表存储相同类型的多重数据。相同的值可以多次出现在一个数组的不同位置中。
Swift 数组对存储数据有具体要求。 不同于 Objective-C 的`NSArray``NSMutableArray`类,们可以存储任何类型的实例而且不提供们返回对象的任何本质信息。 在 Swift 中,数据值在被存储进入某个数组之前类型必须明确,方法是通过显式的类型标注或类型推断,而且不是必须是`class`类型。例如: 如果我们创建了一个`Int`值类型的数组,我们不能往其中插入任何不是`Int`类型的数据。 Swift 中的数组是类型安全的,并且它们中包含的类型必须明确。
Swift 数组对存储数据有具体要求。 不同于 Objective-C 的`NSArray``NSMutableArray`类,们可以存储任何类型的实例而且不提供们返回对象的任何本质信息。 在 Swift 中,数据值在被存储进入某个数组之前类型必须明确,方法是通过显式的类型标注或类型推断,而且不是必须是`class`类型。例如: 如果我们创建了一个`Int`值类型的数组,我们不能往其中插入任何不是`Int`类型的数据。 Swift 中的数组是类型安全的,并且它们中包含的类型必须明确。
<a name="array_type_shorthand_syntax"></a>
### 数组的简单语法
@ -34,7 +34,7 @@ Swift 数组对存储数据有具体要求。 不同于 Objective-C 的`NSArray`
<a name="array_literals"></a>
### 数组构造语句
我们可以使用字面语句来进行数组构造,这是一种用一个或者多个数值构造数组的简单方法。字面语句是一系列由逗号分割并由方括号包含的数值。
我们可以使用字面来进行数组构造,这是一种用一个或者多个数值构造数组的简单方法。字面是一系列由逗号分割并由方括号包含的数值。
`[value 1, value 2, value 3]`
下面这个例子创建了一个叫做`shoppingList`并且存储字符串的数组:
@ -42,19 +42,19 @@ Swift 数组对存储数据有具体要求。 不同于 Objective-C 的`NSArray`
var shoppingList: String[] = ["Eggs", "Milk"]
// shoppingList 已经被构造并且拥有两个初始项。
`shoppingList`变量被声明为“字符串值类型的数组“,记作`String[]`。 因为这个数组被规定只有`String`一种数据结构,所以只有`String`类型可以在其中被存取。 在这里,`shoppinglist`数组由两个`String`值(`"Eggs"``"Milk"`)构造,并且由字面语句定义。
`shoppingList`变量被声明为“字符串值类型的数组“,记作`String[]`。 因为这个数组被规定只有`String`一种数据结构,所以只有`String`类型可以在其中被存取。 在这里,`shoppinglist`数组由两个`String`值(`"Eggs"``"Milk"`)构造,并且由字面定义。
> 注意:
>
> `Shoppinglist`数组被声明为变量(`var`关键字创建)而不是常量(`let`创建)是因为以后可能会有更多的数据项被插入其中。
在这个例子中,字面语句仅仅包含两个`String`值。匹配了该数组的变量声明(只能包含`String`的数组),所以这个字面语句的分配过程就是允许用两个初始项来构造`shoppinglist`
在这个例子中,字面仅仅包含两个`String`值。匹配了该数组的变量声明(只能包含`String`的数组),所以这个字面的分配过程就是允许用两个初始项来构造`shoppinglist`
由于 Swift 的类型推断机制,当我们用字面语句构造只拥有相同类型值数组的时候,我们不必把数组的类型定义清楚。 `shoppinglist`的构造也可以这样写:
由于 Swift 的类型推断机制,当我们用字面构造只拥有相同类型值数组的时候,我们不必把数组的类型定义清楚。 `shoppinglist`的构造也可以这样写:
var shoppingList = ["Eggs", "Milk"]
因为所有字面语句中的值都是相同的类型Swift 可以推断出`String[]``shoppinglist`中变量的正确类型。
因为所有字面中的值都是相同的类型Swift 可以推断出`String[]``shoppinglist`中变量的正确类型。
<a name="accessing_and_modifying_an_array"></a>
### 访问和修改数组
@ -108,7 +108,7 @@ Swift 数组对存储数据有具体要求。 不同于 Objective-C 的`NSArray`
> 注意:
>
>我们不能使用下标语法在数组尾部添加新项。如果我们试着用这种方法对索引越界的数据进行检索或者设置新值的操作,我们会引发一个运行错误。我们可以使用索引值和数组的`count`属性进行比较来在使用某个索引之前先检验是否有效。除了当`count`等于 0 时(说明这是个空数组),最大索引值一直是`count - 1`,因为数组都是零起索引。
>我们不能使用下标语法在数组尾部添加新项。如果我们试着用这种方法对索引越界的数据进行检索或者设置新值的操作,我们会引发一个运行错误。我们可以使用索引值和数组的`count`属性进行比较来在使用某个索引之前先检验是否有效。除了当`count`等于 0 时(说明这是个空数组),最大索引值一直是`count - 1`,因为数组都是零起索引。
调用数组的`insert(atIndex:)`方法来在某个具体索引值之前添加数据项:
@ -151,7 +151,7 @@ Swift 数组对存储数据有具体要求。 不同于 Objective-C 的`NSArray`
// Baking Powder
// Bananas
如果我们同时需要每个数据项的值和索引值,可以使用全局`enumerate`函数来进行数组遍历。`enumerate`返回一个由每一个数据项索引值和数据值组成的键值对组。我们可以把这个键值对组分解成临时常量或者变量来进行遍历:
如果我们同时需要每个数据项的值和索引值,可以使用全局`enumerate`函数来进行数组遍历。`enumerate`返回一个由每一个数据项索引值和数据值组成的组。我们可以把这个组分解成临时常量或者变量来进行遍历:
for (index, value) in enumerate(shoppingList) {
println("Item \(index + 1): \(value)")
@ -200,7 +200,7 @@ Swift 中的`Array`类型还提供一个可以创建特定大小并且所有数
<a name="dictionaries"></a>
## 字典
字典是一种存储相同类型多重数据的存储器。每个值value都关联独特的键key键作为字典中的这个值数据的标识符。和数组中的数据项不同字典中的数据项并没有具体顺序。我们在需要通过标识符访问数据的时候使用字典这种方法很大程度上和我们在现实世界中使用字典查字义的方法一样。
字典是一种存储多个相同类型的值的容器。每个值value都关联唯一的键key键作为字典中的这个值数据的标识符。和数组中的数据项不同字典中的数据项并没有具体顺序。我们在需要通过标识符访问数据的时候使用字典这种方法很大程度上和我们在现实世界中使用字典查字义的方法一样。
Swift 的字典使用时需要具体规定可以存储键和值类型。不同于 Objective-C 的`NSDictionary``NSMutableDictionary` 类可以使用任何类型的对象来作键和值并且不提供任何关于这些对象的本质信息。在 Swift 中,在某个特定字典中可以存储的键和值必须提前定义清楚,方法是通过显性类型标注或者类型推断。
@ -209,11 +209,11 @@ Swift 的字典使用`Dictionary<KeyType, ValueType>`定义,其中`KeyType`是
`KeyType`的唯一限制就是可哈希的,这样可以保证它是独一无二的,所有的 Swift 基本类型(例如`String``Int` `Double``Bool`)都是默认可哈希的,并且所有这些类型都可以在字典中当做键使用。未关联值的枚举成员(参见[枚举](08_Enumerations.html))也是默认可哈希的。
<a name="dictionary_literals"></a>
## 字典字面语句
## 字典字面
我们可以使用字典字面语句来构造字典,们和我们刚才介绍过的数组字面语句拥有相似语法。一个字典字面语句是一个定义拥有一个或者多个键值对的字典集合的简单语句。
我们可以使用字典字面来构造字典,们和我们刚才介绍过的数组字面拥有相似语法。一个字典字面是一个定义拥有一个或者多个键值对的字典集合的简单语句。
一个键值对是一个`key`和一个`value`的结合体。在字典字面语句中,每一个键值对的键和值都由冒号分割。这些键值对构成一个列表,其中这些键值对由方括号包含并且由逗号分割:
一个键值对是一个`key`和一个`value`的结合体。在字典字面中,每一个键值对的键和值都由冒号分割。这些键值对构成一个列表,其中这些键值对由方括号包含并且由逗号分割:
[key 1: value 1, key 2: value 2, key 3: value 3]
@ -227,11 +227,11 @@ Swift 的字典使用`Dictionary<KeyType, ValueType>`定义,其中`KeyType`是
>
> `airports`字典被声明为变量(用`var`关键字)而不是常量(`let`关键字)因为后来更多的机场信息会被添加到这个示例字典中。
`airports`字典使用字典字面语句初始化,包含两个键值对。第一对的键是`TYO`,值是`Tokyo`。第二对的键是`DUB`,值是`Dublin`
`airports`字典使用字典字面初始化,包含两个键值对。第一对的键是`TYO`,值是`Tokyo`。第二对的键是`DUB`,值是`Dublin`
这个字典语句包含了两个`String: String`类型的键值对。们对应`airports`变量声明的类型(一个只有`String`键和`String`值的字典)所以这个字典字面语句是构造两个初始数据项的`airport`字典。
这个字典语句包含了两个`String: String`类型的键值对。们对应`airports`变量声明的类型(一个只有`String`键和`String`值的字典)所以这个字典字面是构造两个初始数据项的`airport`字典。
和数组一样,如果我们使用字面语句构造字典就不用把类型定义清楚。`airports`的也可以用这种方法简短定义:
和数组一样,如果我们使用字面构造字典就不用把类型定义清楚。`airports`的也可以用这种方法简短定义:
var airports = ["TYO": "Tokyo", "DUB": "Dublin"]
@ -292,7 +292,7 @@ Swift 的字典使用`Dictionary<KeyType, ValueType>`定义,其中`KeyType`是
<a name="iterating_over_a_dictionary"></a>
### 字典遍历
我们可以使用`for-in`循环来遍历某个字典中的键值对。每一个字典中的数据项都由`(key, value)`元组形式返回,并且我们可以使用暂时性常量或者变量来分解这些元组:
我们可以使用`for-in`循环来遍历某个字典中的键值对。每一个字典中的数据项都由`(key, value)`元组形式返回,并且我们可以使用临时常量或者变量来分解这些元组:
for (airportCode, airportName) in airports {
println("\(airportCode): \(airportName)")
@ -301,7 +301,7 @@ Swift 的字典使用`Dictionary<KeyType, ValueType>`定义,其中`KeyType`是
// LHR: London Heathrow
`for-in`循环请参见[For 循环](05_Control_Flow.html#for_loops)。
我们也可以通过访问`keys`或者`values`属性(都是可遍历集合)检索一个字典的键或者值:
我们也可以通过访问`keys`或者`values`属性(都是可遍历集合)检索一个字典的键或者值:
for airportCode in airports.keys {
println("Airport code: \(airportCode)")
@ -337,7 +337,7 @@ Swift 的字典使用`Dictionary<KeyType, ValueType>`定义,其中`KeyType`是
这个例子创建了一个`Int, String`类型的空字典来储存英语对整数的命名。它的键是`Int`型,值是`String`型。
如果上下文已经提供了信息类型,我们可以使用空字典字面语句来创建一个空字典,记作`[:]`(中括号中放一个冒号):
如果上下文已经提供了信息类型,我们可以使用空字典字面来创建一个空字典,记作`[:]`(中括号中放一个冒号):
namesOfIntegers[16] = "sixteen"
// namesOfIntegers 现在包含一个键值对
@ -351,7 +351,7 @@ Swift 的字典使用`Dictionary<KeyType, ValueType>`定义,其中`KeyType`是
<a name="mutability_of_collections"></a>
## 集合的可变性
数组和字典都是在单个集合中存储可变值。如果我们创建一个数组或者字典并且把它分配成一个变量,这个集合将会是可变的。这意味着我们可以在创建之后添加更多或移除已存在的数据项来改变这个集合的大小。与此相反,如果我们把数组或字典分配成常量,那么就是不可变的,它的大小不能被改变。
数组和字典都是在单个集合中存储可变值。如果我们创建一个数组或者字典并且把它分配成一个变量,这个集合将会是可变的。这意味着我们可以在创建之后添加更多或移除已存在的数据项来改变这个集合的大小。与此相反,如果我们把数组或字典分配成常量,那么就是不可变的,它的大小不能被改变。
对字典来说,不可变性也意味着我们不能替换其中任何现有键所对应的值。不可变字典的内容在被首次设定之后不能更改。
不可变性对数组来说有一点不同,当然我们不能试着改变任何不可变数组的大小,但是我们可以重新设定相对现存索引所对应的值。这使得 Swift 数组在大小被固定的时候依然可以做的很棒。

2
source/chapter2/05_Control_Flow.md Normal file → Executable file
View File

@ -14,7 +14,7 @@
Swift提供了类似 C 语言的流程控制结构,包括可以多次执行任务的`for``while`循环,基于特定条件选择执行不同代码分支的`if``switch`语句,还有控制流程跳转到其他代码的`break``continue`语句。
除了 C 语言里面传统的for条件递增`for-condition-increment`循环Swift 还增加了`for-in`循环用来更简单地遍历数组array字典dictionary区间range字符串string和其他序列类型。
除了 C 语言里面传统的 for 条件递增(`for-condition-increment`循环Swift 还增加了`for-in`循环用来更简单地遍历数组array字典dictionary区间range字符串string和其他序列类型。
Swift 的`switch`语句比 C 语言中更加强大。在 C 语言中,如果某个 case 不小心漏写了`break`,这个 case 就会贯穿fallthrough至下一个 caseSwift 无需写`break`所以不会发生这种贯穿fallthrough的情况。case 还可以匹配更多的类型模式包括区间匹配range matching元组tuple和特定类型的描述。`switch`的 case 语句中匹配的值可以是由 case 体内部临时的常量或者变量决定,也可以由`where`分句描述更复杂的匹配条件。

0
source/chapter2/06_Functions.md Normal file → Executable file
View File

0
source/chapter2/07_Closures.md Normal file → Executable file
View File

0
source/chapter2/08_Enumerations.md Normal file → Executable file
View File

0
source/chapter2/09_Classes_and_Structures.md Normal file → Executable file
View File

0
source/chapter2/10_Properties.md Normal file → Executable file
View File

0
source/chapter2/11_Methods.md Normal file → Executable file
View File

0
source/chapter2/12_Subscripts.md Normal file → Executable file
View File

0
source/chapter2/13_Inheritance.md Normal file → Executable file
View File

0
source/chapter2/14_Initialization.md Normal file → Executable file
View File

0
source/chapter2/15_Deinitialization.md Normal file → Executable file
View File

0
source/chapter2/16_Automatic_Reference_Counting.md Normal file → Executable file
View File

0
source/chapter2/17_Optional_Chaining.md Normal file → Executable file
View File

0
source/chapter2/18_Type_Casting.md Normal file → Executable file
View File

0
source/chapter2/19_Nested_Types.md Normal file → Executable file
View File

0
source/chapter2/20_Extensions.md Normal file → Executable file
View File

0
source/chapter2/21_Protocols.md Normal file → Executable file
View File

0
source/chapter2/22_Generics.md Normal file → Executable file
View File

0
source/chapter2/23_Advanced_Operators.md Normal file → Executable file
View File

0
source/chapter2/chapter2.md Normal file → Executable file
View File

0
source/chapter3/01_About_the_Language_Reference.md Normal file → Executable file
View File

0
source/chapter3/02_Lexical_Structure.md Normal file → Executable file
View File

0
source/chapter3/03_Types.md Normal file → Executable file
View File

0
source/chapter3/04_Expressions.md Normal file → Executable file
View File

0
source/chapter3/05_Declarations.md Normal file → Executable file
View File

0
source/chapter3/06_Attributes.md Normal file → Executable file
View File

0
source/chapter3/07_Patterns.md Normal file → Executable file
View File

0
source/chapter3/08_Generic_Parameters_and_Arguments.md Normal file → Executable file
View File

0
source/chapter3/09_Summary_of_the_Grammar.md Normal file → Executable file
View File

0
source/chapter3/10_Statements.md Normal file → Executable file
View File

0
source/chapter3/chapter3.md Normal file → Executable file
View File