From 739176f3805f90b58ac2fbddfadf7bb46c3432b3 Mon Sep 17 00:00:00 2001 From: Fan SC <941977129@qq.com> Date: Sun, 5 Jun 2022 03:05:29 +0800 Subject: [PATCH] Update 21_Protocols.md (#1188) --- source/02_language_guide/21_Protocols.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/02_language_guide/21_Protocols.md b/source/02_language_guide/21_Protocols.md index 92f525f6..770542a6 100644 --- a/source/02_language_guide/21_Protocols.md +++ b/source/02_language_guide/21_Protocols.md @@ -272,7 +272,7 @@ class Dice { 例子中定义了一个 `Dice` 类,用来代表桌游中拥有 N 个面的骰子。`Dice` 的实例含有 `sides` 和 `generator` 两个属性,前者是整型,用来表示骰子有几个面,后者为骰子提供一个随机数生成器,从而生成随机点数。 -`generator` 属性的类型为 `RandomNumberGenerator`,因此任何遵循了 `RandomNumberGenerator` 协议的类型的实例都可以赋值给 `generator`,除此之外并无其他要求。并且由于其类型是 `RandomNumberGenerator`,在 `Dice` 类中与 `generator` 交互的代码,必须适用于所有 `generator` 实例都遵循的方法。这句话的意思是不能使用由 `generator` 底层类型提供的任何方法或属性。但是你可以通过向下转型,从协议类型转换成底层实现类型,比如从父类向下转型为子类。请参考 [向下转型](./18_Type_Casting.md#downcasting)。 +`generator` 属性的类型为 `RandomNumberGenerator`,因此任何遵循了 `RandomNumberGenerator` 协议的类型的实例都可以赋值给 `generator`,除此之外并无其他要求。并且由于其类型是 `RandomNumberGenerator`,所以在 `Dice` 类中与 `generator` 交互的代码,必须适用于所有遵循该协议的 `generator` 实例。这意味着不能使用由 `generator` 的底层类型定义的任何方法或属性。但是,你可以从协议类型转换成底层实现类型,就像从父类向下转型为子类一样。请参考 [向下转型](./18_Type_Casting.md#downcasting)。 `Dice` 类还有一个构造器,用来设置初始状态。构造器有一个名为 `generator`,类型为 `RandomNumberGenerator` 的形参。在调用构造方法创建 `Dice` 的实例时,可以传入任何遵循 `RandomNumberGenerator` 协议的实例给 `generator`。 @@ -632,7 +632,7 @@ print(game.prettyTextualDescription) ## 类专属的协议 {#class-only-protocol} -你通过添加 `AnyObject` 关键字到协议的继承列表,就可以限制协议只能被类类型采纳(以及非结构体或者非枚举的类型)。 +你通过添加 `AnyObject` 关键字到协议的继承列表,就可以限制协议只能被类类型遵循(而不能是结构体类型或者枚举类型)。 ```swift protocol SomeClassOnlyProtocol: AnyObject, SomeInheritedProtocol { @@ -826,7 +826,7 @@ class Counter { `increment()` 方法首先试图使用 `increment(forCount:)` 方法来得到每次的增量。`increment()` 方法使用可选链式调用来尝试调用 `increment(forCount:)`,并将当前的 `count` 值作为参数传入。 -这里使用了两层可选链式调用。首先,由于 `dataSource` 可能为 `nil`,因此在 `dataSource` 后边加上了 `?`,以此表明只在 `dataSource` 非空时才去调用 `increment(forCount:)` 方法。其次,即使 `dataSource` 存在,也无法保证其是否实现了 `increment(forCount:)` 方法,因为这个方法是可选的。因此,`increment(forCount:)` 方法同样使用可选链式调用进行调用,只有在该方法被实现的情况下才能调用它,所以在 `increment(forCount:)` 方法后边也加上了 `?`。 +这里使用了两层可选链式调用。首先,由于 `dataSource` 可能为 `nil`,因此在 `dataSource` 后边加上了 `?`,以此表明只在 `dataSource` 非空时才去调用 `increment(forCount:)` 方法。其次,即使 `dataSource` 存在,也无法保证其是否实现了 `increment(forCount:)` 方法,因为这个方法是可选的。因此,`increment(forCount:)` 方法同样使用可选链式调用进行调用,只有在该方法被实现的情况下才能调用它,所以在 `increment(forCount:)` 方法名称后边也加上了 `?`。 调用 `increment(forCount:)` 方法在上述两种情形下都有可能失败,所以返回值为 `Int?` 类型。虽然在 `CounterDataSource` 协议中,`increment(forCount:)` 的返回值类型是非可选 `Int`。另外,即使这里使用了两层可选链式调用,最后的返回结果依旧是单层的可选类型。关于这一点的更多信息,请查阅 [连接多层可选链式调用](./16_Optional_Chaining.md)。