diff --git a/source/chapter3/04_Expressions.md b/source/chapter3/04_Expressions.md
index 83f70043..26258390 100644
--- a/source/chapter3/04_Expressions.md
+++ b/source/chapter3/04_Expressions.md
@@ -14,6 +14,9 @@
> 2.2
> 校对:[175](https://github.com/Brian175)
+> 3.0
+> 翻译+校对:[chenmingjia](https://github.com/chenmingjia)
+
本页包含内容:
- [前缀表达式](#prefix_expressions)
@@ -530,41 +533,52 @@ x = .AnotherValue
### 选择器表达式
-可通过选择器表达式来获取引用 Objective-C 方法的选择器。
+选择器表达式可以让你通过选择器来引用在Objective-C中方法(method)和属性(property)的setter和getter方法。
> \#selector(方法名)
+\#selector(getter: 属性名)
+\#selector(setter: 属性名)
-方法名必须是存在于 Objective-C 运行时中的方法的引用。选择器表达式的返回值是一个 `Selector` 类型的实例。例如:
+方法名和属性名必须是存在于 Objective-C 运行时中的方法和属性的引用。选择器表达式的返回值是一个 Selector 类型的实例。例如:
```swift
class SomeClass: NSObject {
+ let property: String
@objc(doSomethingWithInt:)
- func doSomething(x: Int) { }
+ func doSomething(_ x: Int) { }
+
+ init(property: String) {
+ self.property = property
+ }
}
-let x = SomeClass()
-let selector = #selector(x.doSomething(_:))
+let selectorForMethod = #selector(SomeClass.doSomething(_:))
+let selectorForPropertyGetter = #selector(getter: SomeClass.property)
```
+当为属性的getter创建选择器时,属性名可以是变量属性或者常量属性的引用。但是当为属性的setter创建选择器时,属性名只可以是对变量属性的引用。
-具有相同方法名但类型不同的方法可以使用 `as` 操作符来区分:
+方法名称可以包含圆括号来进行分组,并使用as 操作符来区分具有相同方法名但类型不同的方法, 例如:
```swift
extension SomeClass {
@objc(doSomethingWithString:)
- func doSomething(x: String) { }
+ func doSomething(_ x: String) { }
}
-let anotherSelector = #selector(x.doSomething(_:) as (String) -> Void)
+let anotherSelector = #selector(SomeClass.doSomething(_:) as (SomeClass) -> (String) -> Void)
```
-由于选择器是在编译时创建的,因此编译器可以检查方法是否存在,以及方法是否在运行时暴露给了 Objective-C 。
+由于选择器是在编译时创建的,因此编译器可以检查方法或者属性是否存在,以及是否在运行时暴露给了 Objective-C 。
> 注意
-> 虽然方法名是个表达式,但是它不会被求值。
+> 虽然方法名或者属性名是个表达式,但是它不会被求值。
-更多关于如何在 Swift 代码中使用选择器来与 Objective-C API 进行交互的信息,请参阅 [*Using Swift with Cocoa and Objective-C*](https://developer.apple.com/library/ios/documentation/Swift/Conceptual/BuildingCocoaApps/index.html#//apple_ref/doc/uid/TP40014216) 中的 [*Objective-C Selectors*](https://developer.apple.com/library/ios/documentation/Swift/Conceptual/BuildingCocoaApps/InteractingWithObjective-CAPIs.html#//apple_ref/doc/uid/TP40014216-CH4-ID59) 部分。
+更多关于如何在 Swift 代码中使用选择器来与 Objective-C API 进行交互的信息,请参阅 [Using Swift with Cocoa and Objective-C (Swift 3)](https://developer.apple.com/library/prerelease/content/documentation/Swift/Conceptual/BuildingCocoaApps/index.html#//apple_ref/doc/uid/TP40014216) 中[Objective-C Selectors](https://developer.apple.com/library/prerelease/content/documentation/Swift/Conceptual/BuildingCocoaApps/InteractingWithObjective-CAPIs.html#//apple_ref/doc/uid/TP40014216-CH4-ID59)部分。
> 选择器表达式语法
-> *选择器表达式* → __#selector__ **(** [*表达式*](#expression) **)**
+> *选择器表达式* → __#selector__ **(** [*表达式*](#expression) **)**
+> *选择器表达式* → __#selector__ **(** [*getter:表达式*](#expression) **)**
+> *选择器表达式* → __#selector__ **(** [*setter:表达式*](#expression) **)**
+
## 后缀表达式
@@ -752,11 +766,11 @@ let x = [10, 3, 20, 15, 4]
### dynamicType 表达式
-`dynamicType` 表达式由某个表达式紧跟 `.dynamicType` 组成,其形式如下:
+dynamicType 表达式由类似[函数调用表达式(Function Call Expression)](#function-call-expression)的特殊语法表达式组成,形式如下:
-> `表达式`.dynamicType
+> type(of:`表达式`)
-上述形式中的表达式不能是类型名。`dynamicType` 表达式会返回某个实例在运行时的类型,具体请看下面的例子:
+上述形式中的表达式不能是类型名。type(of:) 表达式会返回某个实例在运行时的类型,具体请看下面的例子:
```swift
class SomeBaseClass {
@@ -772,13 +786,13 @@ class SomeSubClass: SomeBaseClass {
let someInstance: SomeBaseClass = SomeSubClass()
// someInstance 在编译时的静态类型为 SomeBaseClass,
// 在运行时的动态类型为 SomeSubClass
-someInstance.dynamicType.printClassName()
+type(of: someInstance).printClassName()
// 打印 “SomeSubClass”
```
> 动态类型表达式语法
-> *动态类型表达式* → [*后缀表达式*](#postfix-expression) **.** **dynamicType**
+> *动态类型表达式* → type(of:表达式) **.** **dynamicType**
### 下标表达式
diff --git a/source/chapter3/08_Generic_Parameters_and_Arguments.md b/source/chapter3/08_Generic_Parameters_and_Arguments.md
index 40070f67..84e92707 100755
--- a/source/chapter3/08_Generic_Parameters_and_Arguments.md
+++ b/source/chapter3/08_Generic_Parameters_and_Arguments.md
@@ -8,6 +8,9 @@
> 2.0
> 翻译+校对:[wardenNScaiyi](https:github.com/wardenNScaiyi)
+> 3.0
+> 翻译+校对:[chenmingjia](https:github.com/chenmingjia)
+
本页包含内容:
- [泛型形参子句](#generic_parameter)
@@ -21,10 +24,9 @@
## 泛型形参子句
-泛型形参子句指定泛型类型或函数的类型形参,以及这些参数相关的约束和要求。泛型形参子句用尖括号(`<>`)包住,并且有以下两种形式:
+泛型形参子句指定泛型类型或函数的类型形参,以及这些参数相关的约束和要求。泛型形参子句用尖括号(`<>`)包住,形式如下:
> <`泛型形参列表`>
-> <`泛型形参列表` where `类型要求`>
泛型形参列表中泛型形参用逗号分开,其中每一个采用以下形式:
@@ -36,7 +38,7 @@
```swift
-func simpleMax(x: T, _ y: T) -> T {
+func simpleMax(_ x: T, _ y: T) -> T {
if x < y {
return y
}
@@ -54,18 +56,19 @@ simpleMax(3.14159, 2.71828) // T 被推断为 Double 类型
### Where 子句
-要想对类型形参及其关联类型指定额外要求,可以在泛型形参列表之后添加 `where` 子句。`where` 子句由关键字 `where` 及其后的用逗号分隔的一个或多个要求组成。
+要想对类型形参及其关联类型指定额外要求,可以在函数体或者类型的大括号之前添加 `where` 子句。`where` 子句由关键字 `where` 及其后的用逗号分隔的一个或多个要求组成。
-`where` 子句中的要求用于指明该类型形参继承自某个类或符合某个协议或协议组合。尽管 `where` 子句提供了语法糖使其有助于表达类型形参上的简单约束(如 `T: Comparable` 等同于 `T where T: Comparable`,等等),但是依然可以用来对类型形参及其关联类型提供更复杂的约束。如,`` 表示泛型类型 `T` 继承自类 `C` 且符合协议 `P`。
+> `where` : `类型要求`
-如上所述,可以强制约束类型形参的关联类型符合某个协议。例如 `` 表示 `S` 符合 `SequenceType` 协议,而且 `S` 的关联类型 `S.Generator.Element` 符合 `Eauatable` 协议。这种约束确保了序列中的每个元素都是符合 `Equatable` 协议的。
+`where` 子句中的要求用于指明该类型形参继承自某个类或符合某个协议或协议组合。尽管 `where` 子句提供了语法糖使其有助于表达类型形参上的简单约束(如 `` 等同于 ` where T: Comparable`,等等),但是依然可以用来对类型形参及其关联类型提供更复杂的约束,例如你可以强制形参的关联类型遵守协议,如,` where S.Iterator.Element: Equatable` 表示泛型类型 `S` 遵守`Sequence`协议并且关联类型`S.Iterator.Element`遵守`Equatable`协议,这个约束确保队列的每一个元素都是符合 `Equatable` 协议的。
-也可以用操作符 `==` 来指定两个类型必须相同。例如,泛型形参子句 `` 表示 `S1` 和 `S2` 必须都符合 `SequenceType` 协议,而且两个序列中的元素类型必须相同。
+也可以用操作符 `==` 来指定两个类型必须相同。例如,泛型形参子句 ` where S1.Iterator.Element == S2.Iterator.Element` 表示 `S1` 和 `S2` 必须都符合 `SequenceType` 协议,而且两个序列中的元素类型必须相同。
当然,替代类型形参的类型实参必须满足所有的约束和要求。
泛型函数或构造器可以重载,但在泛型形参子句中的类型形参必须有不同的约束或要求,抑或二者皆不同。当调用重载的泛型函数或构造器时,编译器会根据这些约束来决定调用哪个重载函数或构造器。
+更多关于泛型where从句的信息和关于泛型函数声明的例子,可以看一看 [泛型where子句](https://github.com/numbbbbb/the-swift-programming-language-in-chinese/blob/gh-pages/source/chapter2/23_Generics.md#where_clauses)
> 泛型形参子句语法
@@ -99,7 +102,7 @@ simpleMax(3.14159, 2.71828) // T 被推断为 Double 类型
> <`泛型实参列表`>
-泛型实参列表中类型实参用逗号分开。类型实参是实际具体类型的名字,用来替代泛型类型的泛型形参子句中的相应的类型形参。从而得到泛型类型的一个特化版本。例如,Swift 标准库中的泛型字典类型定义如下:
+泛型实参列表中类型实参用逗号分开。类型实参是实际具体类型的名字,用来替代泛型类型的泛型形参子句中的相应的类型形参。从而得到泛型类型的一个特化版本。例如,Swift 标准库中的泛型字典类型的的简化定义如下:
```swift
struct Dictionary: CollectionType, DictionaryLiteralConvertible {