修正编辑错误 (#857)

* 19_Nested_Types 去除多余空格

* 清除行末多余空格

* 20_Extensions 标题后添加空行

* 20_Extensions 修正注释翻译

* 20_Extensions 修正行内代码块引用方式

* 21_Protocols 修正编辑中的错误
This commit is contained in:
BqLin
2019-01-18 22:47:32 +08:00
committed by Jie Liang
parent 85b457b8ca
commit 1493185ba4
4 changed files with 89 additions and 85 deletions

View File

@ -18,7 +18,8 @@ Swift 中的扩展可以:
> 扩展可以给一个类型添加新的功能,但是不能重写已经存在的功能。
## 扩展的语法
使用 **extension** 关键字声明扩展:
使用 `extension` 关键字声明扩展:
```swift
extension SomeType {
@ -43,7 +44,8 @@ extension SomeType: SomeProtocol, AnotherProtocol {
> 对一个现有的类型,如果你定义了一个扩展来添加新的功能,那么这个类型的所有实例都可以使用这个新功能,包括那些在扩展定义之前就存在的实例。
## 计算型属性
扩展可以给现有类型添加计算型实例属性和计算型类属性。这个例子给 Swift 内建的 **Double** 类型添加了五个计算型实例属性,从而提供与距离单位相关工作的基本支持:
扩展可以给现有类型添加计算型实例属性和计算型类属性。这个例子给 Swift 内建的 `Double` 类型添加了五个计算型实例属性,从而提供与距离单位相关工作的基本支持:
```swift
extension Double {
@ -55,24 +57,24 @@ extension Double {
}
let oneInch = 25.4.mm
print("One inch is \(oneInch) meters")
// 打印“一英寸是 0.0254 米”
// 打印“One inch is 0.0254 meters”
let threeFeet = 3.ft
print("Three feet is \(threeFeet) meters")
// 打印“三英尺是 0.914399970739201
// 打印“Three feet is 0.914399970739201 meters
```
这些计算型属性表示的含义是把一个 **Double** 值看作是某单位下的长度值。即使它们被实现为计算型属性,但这些属性的名字仍可紧接一个浮点型字面值,从而通过点语法来使用,并以此实现距离转换。
这些计算型属性表示的含义是把一个 `Double` 值看作是某单位下的长度值。即使它们被实现为计算型属性,但这些属性的名字仍可紧接一个浮点型字面值,从而通过点语法来使用,并以此实现距离转换。
在上述例子中,**Double** 类型的 **1.0** 代表的是“一米”。这就是为什么计算型属性 **m** 返回的是 **self** - 表达式 **1.m** 被认为是计算一个 **Double** 类型的 **1.0**
在上述例子中,`Double` 类型的 `1.0` 代表的是“一米”。这就是为什么计算型属性 `m` 返回的是 `self`——表达式 `1.m` 被认为是计算一个 `Double` 类型的 `1.0`
其它单位则需要一些单位换算。一千米等于 1,000 米,所以计算型属性 **km** 要把值乘以 **1_000.00** 来实现千米到米的单位换算。类似地,一米有 3.28084 英尺,所以计算型属性 **ft** 要把对应的 **Double** 值除以 **3.28084**,来实现英尺到米的单位换算。
其它单位则需要一些单位换算。一千米等于 1,000 米,所以计算型属性 `km` 要把值乘以 `1_000.00` 来实现千米到米的单位换算。类似地,一米有 3.28084 英尺,所以计算型属性 `ft` 要把对应的 `Double` 值除以 `3.28084`,来实现英尺到米的单位换算。
这些属性都是只读的计算型属性,所以为了简便,它们的表达式里面都不包含 **get** 关键字。它们使用 **Double** 作为返回值类型,并可用于所有接受 **Double** 类型的数学计算中:
这些属性都是只读的计算型属性,所以为了简便,它们的表达式里面都不包含 `get` 关键字。它们使用 `Double` 作为返回值类型,并可用于所有接受 `Double` 类型的数学计算中:
```swift
let aMarathon = 42.km + 195.m
print("A marathon is \(aMarathon) meters long")
// 打印“马拉松赛跑全长 42195.0 米。
// 打印“A marathon is 42195.0 meters long
```
> 注意
@ -80,15 +82,16 @@ print("A marathon is \(aMarathon) meters long")
> 扩展可以添加新的计算属性,但是它们不能添加存储属性,或向现有的属性添加属性观察者。
## 构造器
扩展可以给现有的类型添加新的构造器。它使你可以把自定义类型作为参数来供其他类型的构造器使用,或者在类型的原始实现上添加额外的构造选项。
扩展可以给一个类添加新的便利构造器,但是它们不能给类添加新的指定构造器或者析构器。指定构造器和析构器必须始终由类的原始实现提供。
如果你使用扩展给一个值类型添加构造器只是用于给所有的存储属性提供默认值,并且没有定义任何自定义构造器,那么你可以在该值类型扩展的构造器中使用默认构造器和成员构造器。如果你把构造器写到了值类型的原始实现中,就像 [值类型的构造器委托](https://docs.swift.org/swift-book/LanguageGuide/Initialization.html#ID215) 中所描述的,那么就不属于在扩展中添加构造器。
如果你使用扩展给另一个模块中定义的结构体添加构造器,那么新的构造器直到定义模块中使用一个构造器之前,不能访问 **self**
如果你使用扩展给另一个模块中定义的结构体添加构造器,那么新的构造器直到定义模块中使用一个构造器之前,不能访问 `self`
在下面的例子中,自定义了一个的 **Rect** 结构体用来表示一个几何矩形。这个例子中还定义了两个给予支持的结构体 **Size** **Point**,它们都把属性的默认值设置为 **0.0**
在下面的例子中,自定义了一个的 `Rect` 结构体用来表示一个几何矩形。这个例子中还定义了两个给予支持的结构体 `Size``Point`,它们都把属性的默认值设置为 `0.0`
```swift
struct Size {
@ -103,7 +106,7 @@ struct Rect {
}
```
因为 **Rect** 结构体给所有的属性都提供了默认值,所以它自动获得了一个默认构造器和一个成员构造器,就像 [默认构造器](https://docs.swift.org/swift-book/LanguageGuide/Initialization.html#ID213) 中描述的一样。这些构造器可以用来创建新的 **Rect** 实例:
因为 `Rect` 结构体给所有的属性都提供了默认值,所以它自动获得了一个默认构造器和一个成员构造器,就像 [默认构造器](https://docs.swift.org/swift-book/LanguageGuide/Initialization.html#ID213) 中描述的一样。这些构造器可以用来创建新的 `Rect` 实例:
```swift
let defaultRect = Rect()
@ -111,7 +114,7 @@ let memberwiseRect = Rect(origin: Point(x: 2.0, y: 2.0),
size: Size(width: 5.0, height: 5.0))
```
你可以通过扩展 **Rect** 结构体来提供一个允许指定 point size 的构造器:
你可以通过扩展 `Rect` 结构体来提供一个允许指定 pointsize 的构造器:
```swift
extension Rect {
@ -123,7 +126,7 @@ extension Rect {
}
```
这个新的构造器首先根据提供的 **center****size** 计算一个适当的原点。然后这个构造器调用结构体自带的成员构造器 **init(origin:size:)**,它会将新的 origin 和 size 值储存在适当的属性中:
这个新的构造器首先根据提供的 `center``size` 计算一个适当的原点。然后这个构造器调用结构体自带的成员构造器 `init(origin:size:)`,它会将新的 origin 和 size 值储存在适当的属性中:
```swift
let centerRect = Rect(center: Point(x: 4.0, y: 4.0),
@ -136,7 +139,8 @@ let centerRect = Rect(center: Point(x: 4.0, y: 4.0),
> 如果你通过扩展提供一个新的构造器,你有责任确保每个通过该构造器创建的实例都是初始化完整的。
## 方法
扩展可以给现有类型添加新的实例方法和类方法。在下面的例子中,给 **Int** 类型添加了一个新的实例方法叫做 **repetitions**
扩展可以给现有类型添加新的实例方法和类方法。在下面的例子中,给 `Int` 类型添加了一个新的实例方法叫做 `repetitions`
```swift
extension Int {
@ -148,9 +152,9 @@ extension Int {
}
```
**repetitions(task:)** 方法仅接收一个 **() -> Void** 类型的参数,它表示一个没有参数没有返回值的方法。
`repetitions(task:)` 方法仅接收一个 `() -> Void` 类型的参数,它表示一个没有参数没有返回值的方法。
定义了这个扩展之后,你可以对任意整形数值调用 **repetitions(task:)** 方法,来执行对应次数的任务:
定义了这个扩展之后,你可以对任意整形数值调用 `repetitions(task:)` 方法,来执行对应次数的任务:
```swift
3.repetitions {
@ -162,9 +166,10 @@ extension Int {
```
### 可变实例方法
通过扩展添加的实例方法同样也可以修改(或 *mutating(改变)*)实例本身。结构体和枚举的方法,若是可以修改 **self** 或者它自己的属性,则必须将这个实例方法标记为 **mutating**,就像是改变了方法的原始实现。
在下面的例子中,对 Swift **Int** 类型添加了一个新的 mutating 方法,叫做 **square**,它将原始值求平方:
通过扩展添加的实例方法同样也可以修改(或 *mutating改变*)实例本身。结构体和枚举的方法,若是可以修改 `self` 或者它自己的属性,则必须将这个实例方法标记为 `mutating`,就像是改变了方法的原始实现。
在下面的例子中,对 Swift 的 `Int` 类型添加了一个新的 mutating 方法,叫做 `square`,它将原始值求平方:
```swift
extension Int {
@ -178,10 +183,11 @@ someInt.square()
```
## 下标
扩展可以给现有的类型添加新的下标。下面的例子中,对 Swift **Int** 类型添加了一个整数类型的下标。下标 **[n]** 从数字右侧开始,返回小数点后的第 **n** 位:
- **123456789[0]** returns **9**
- **123456789[1]** returns **8**
扩展可以给现有的类型添加新的下标。下面的例子中,对 Swift 的 `Int` 类型添加了一个整数类型的下标。下标 `[n]` 从数字右侧开始,返回小数点后的第 `n` 位:
- `123456789[0]` 返回 `9`
- `123456789[1]` 返回 `8`
……以此类推:
```swift
@ -195,16 +201,16 @@ extension Int {
}
}
746381295[0]
// returns 5
// 返回 5
746381295[1]
// returns 9
// 返回 9
746381295[2]
// returns 2
// 返回 2
746381295[8]
// returns 7
// 返回 7
```
如果操作的 **Int** 值没有足够的位数满足所请求的下标,那么下标的现实将返回 **0**,将好像在数字的左边补上了 0
如果操作的 `Int` 值没有足够的位数满足所请求的下标,那么下标的现实将返回 `0`,将好像在数字的左边补上了 0
```swift
746381295[9]
@ -213,6 +219,7 @@ extension Int {
```
## 嵌套类型
扩展可以给现有的类,结构体,还有枚举添加新的嵌套类型:
```swift
@ -233,11 +240,11 @@ extension Int {
}
```
这个例子给 **Int** 添加了一个新的嵌套枚举。这个枚举叫做 **Kind**,表示特定整数所代表的数字类型。具体来说,它表示数字是负的、零的还是正的。
这个例子给 `Int` 添加了一个新的嵌套枚举。这个枚举叫做 `Kind`,表示特定整数所代表的数字类型。具体来说,它表示数字是负的、零的还是正的。
这个例子同样给 **Int** 添加了一个新的计算型实例属性,叫做 **kind**,它返回被操作整数所对应的 **Kind** 枚举 case 分支。
这个例子同样给 `Int` 添加了一个新的计算型实例属性,叫做 `kind`,它返回被操作整数所对应的 `Kind` 枚举 case 分支。
现在,任意 **Int** 的值都可以使用这个嵌套类型:
现在,任意 `Int` 的值都可以使用这个嵌套类型:
```swift
func printIntegerKinds(_ numbers: [Int]) {
@ -257,10 +264,8 @@ printIntegerKinds([3, 19, -27, 0, -6, 0, 7])
// 打印“+ + - 0 - 0 + ”
```
方法 **printIntegerKinds(_:)**,使用一个 **Int** 类型的数组作为输入,然后依次迭代这些值。对于数组中的每一个整数,方法会检查它的 **kind** 计算型属性,然后打印适当的描述。
方法 `printIntegerKinds(_:)`,使用一个 `Int` 类型的数组作为输入,然后依次迭代这些值。对于数组中的每一个整数,方法会检查它的 `kind` 计算型属性,然后打印适当的描述。
> 注意
>
> **number.kind** 已经被认为是 **Int.Kind** 类型。所以,在 **switch** 语句中所有的 **Int.Kind** case 分支可以被缩写,就像使用 **.negative** 替代 **Int.Kind.negative.**
> `number.kind` 已经被认为是 `Int.Kind` 类型。所以,在 `switch` 语句中所有的 `Int.Kind` case 分支可以被缩写,就像使用 `.negative` 替代 `Int.Kind.negative.`

View File

@ -72,7 +72,7 @@ struct Person: FullyNamed {
var fullName: String
}
let john = Person(fullName: "John Appleseed")
// john.fullName 为 "John Appleseed"
// john.fullName 为John Appleseed
```
这个例子中定义了一个叫做 `Person` 的结构体,用来表示一个具有名字的人。从第一行代码可以看出,它遵循了 `FullyNamed` 协议。
@ -94,7 +94,7 @@ class Starship: FullyNamed {
}
}
var ncc1701 = Starship(name: "Enterprise", prefix: "USS")
// ncc1701.fullName 是 "USS Enterprise"
// ncc1701.fullName 是USS Enterprise
```
`Starship` 类把 `fullName` 属性实现为只读的计算型属性。每一个 `Starship` 类的实例都有一个名为 `name` 的非可选属性和一个名为 `prefix` 的可选属性。 当 `prefix` 存在时,计算型属性 `fullName` 会将 `prefix` 插入到 `name` 之前,从而为星际飞船构建一个全名。
@ -659,7 +659,7 @@ func beginConcert(in location: Location & Named) {
let seattle = City(name: "Seattle", latitude: 47.6, longitude: -122.3)
beginConcert(in: seattle)
// Prints "Hello, Seattle!"
// 打印“Hello, Seattle!
```
`beginConcert(in:)` 方法接受一个类型为 `Location & Named` 的参数,这意味着“任何 Location 的子类,并且遵循 Named 协议”。例如City 就满足这样的条件。
@ -753,7 +753,7 @@ for object in objects {
```swift
@objc protocol CounterDataSource {
@objc optional func incrementForCount(count: Int) -> Int
@objc optional func increment(forCount count: Int) -> Int
@objc optional var fixedIncrement: Int { get }
}
```
@ -771,7 +771,7 @@ class Counter {
var count = 0
var dataSource: CounterDataSource?
func increment() {
if let amount = dataSource?.incrementForCount?(count) {
if let amount = dataSource?.increment?(forCount: count) {
count += amount
} else if let amount = dataSource?.fixedIncrement {
count += amount
@ -917,7 +917,6 @@ extension Collection where Element: Equatable {
如果集合中的所有元素都一致,`allEqual()` 方法才返回 `true`
看看两个整数数组,一个数组的所有元素都是一样的,另一个不一样:
```swift