From 48373d7791216e49e99af290e4c936788846d8ca Mon Sep 17 00:00:00 2001 From: sunset wan Date: Wed, 9 Oct 2019 23:43:32 +0800 Subject: [PATCH 01/16] Translation in progress --- source/chapter2/10_Properties.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/source/chapter2/10_Properties.md b/source/chapter2/10_Properties.md index c37d9e9d..c9f43376 100755 --- a/source/chapter2/10_Properties.md +++ b/source/chapter2/10_Properties.md @@ -6,6 +6,8 @@ 另外,还可以定义属性观察器来监控属性值的变化,以此来触发自定义的操作。属性观察器可以添加到类本身定义的存储属性上,也可以添加到从父类继承的属性上。 +你也可以利用属性包装器来复用多个属性的 getter 和 setter 中的代码。 + ## 存储属性 {#stored-properties} 简单来说,一个存储属性就是存储在特定类或结构体实例里的一个常量或变量。存储属性可以是*变量存储属性*(用关键字 `var` 定义),也可以是*常量存储属性*(用关键字 `let` 定义)。 @@ -280,6 +282,27 @@ stepCounter.totalSteps = 896 > > 如果将带有观察器的属性通过 in-out 方式传入函数,`willSet` 和 `didSet` 也会调用。这是因为 in-out 参数采用了拷入拷出内存模式:即在函数内部使用的是参数的 copy,函数结束后,又对参数重新赋值。关于 in-out 参数详细的介绍,请参考 [输入输出参数](../chapter3/05_Declarations.html#in-out_parameters) +## 属性包装器 {#property-wrappers} +属性包装器在管理一个属性是如何存储的代码和定义一个属性的代码之间添加了一层分隔层。举例来说,如果你有一些提供线程安全性检查或者在数据库中存储它们基本数据的属性,你必须对每个属性都添加这段代码。当使用属性包装器时,你只需在定义属性包装器时编写一次管理代码,然后通过把它应用到多个属性上的方式来复用那段管理代码。 + +为了定义一个属性包装器,你需要创建一个定义 `wrappedValue` 属性的结构体、枚举或者类。在下面的代码中,`TwelveOrLess` 结构体确保它包装的值始终包含小于等于12的数字。如果你要求它存储一个更大的数字,它则会存储 12 这个数字。 + +``` +@propertyWrapper +struct TwelveOrLess { + private var number = 0 + var wrappedValue: Int { + get { return number } + set { number = min(newValue, 12) } + } +} +``` + +这个 setter 确保新值小于 12,且这个 getter 返回被存储的值。 +> 注意 +> +> 在上面例子中对 `number` 的声明把这个变量标记为 `private`,这使得 `number` 仅在 `TwelveOrLess` 的实现中使用。写在其他地方的代码通过使用 `wrappedValue` 的 getter 和 setter 来获取这个值,且不能直接使用 `number`。有关 `private` 的更多信息,请参考 [访问控制](./25_Access_Control.md) + ## 全局变量和局部变量 {#global-and-local-variables} 计算属性和观察属性所描述的功能也可以用于*全局变量*和*局部变量*。全局变量是在函数、方法、闭包或任何类型之外定义的变量。局部变量是在函数、方法或闭包内部定义的变量。 From 7ba5a56301f64a5ef6b81171e4a0f87b20ed9993 Mon Sep 17 00:00:00 2001 From: sunset wan Date: Fri, 11 Oct 2019 00:10:57 +0800 Subject: [PATCH 02/16] Translation in progress --- source/chapter2/10_Properties.md | 45 ++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/source/chapter2/10_Properties.md b/source/chapter2/10_Properties.md index c9f43376..e70695a0 100755 --- a/source/chapter2/10_Properties.md +++ b/source/chapter2/10_Properties.md @@ -303,6 +303,51 @@ struct TwelveOrLess { > > 在上面例子中对 `number` 的声明把这个变量标记为 `private`,这使得 `number` 仅在 `TwelveOrLess` 的实现中使用。写在其他地方的代码通过使用 `wrappedValue` 的 getter 和 setter 来获取这个值,且不能直接使用 `number`。有关 `private` 的更多信息,请参考 [访问控制](./25_Access_Control.md) +通过在属性之前写上包装器的名称的方式,你可以把一个包装器应用到一个属性上去,这个包装器的名称作为这个属性的特性。这里有一个存储一个很小的矩形的结构体。这个结构体使用了同样的(相当随意的)由 `TwelveOrLess` 属性包装器实现的“小”的定义。 + +``` +struct SmallRectangle { + @TwelveOrLess var height: Int + @TwelveOrLess var width: Int +} + +var rectangle = SmallRectangle() +print(rectangle.height) +// 打印 "0" + +rectangle.height = 10 +print(rectangle.height) +// 打印 "10" + +rectangle.height = 24 +print(rectangle.height) +// 打印 "12" +``` + +`height` 和 `width` 属性从 `TwelveOrLess` 的定义中获取它们的初始值。该定义把 `TwelveOrLess.number` 设置为 0。把数字 10 存进 `rectangle.height` 中的操作能成功,是因为数字 10 很小。尝试存储 24 的操作实际上存储的值为 12,这是因为对于这个属性的 setter 的规则来说,24 太大了。 + +当你把一个包装器应用到一个属性上时,编译器将合成为包装器提供存储空间的代码和提供通过包装程序访问属性的代码。(属性包装器负责存储被包装的值,所以没有为此合成的代码。)不利用这个特性语法的情况下,你可以写出使用属性包装器行为的代码。举例来说,这是先前代码清单中的 `SmallRectangle` 的一个版本。这个版本将其属性明确地包装在 `TwelveOrLess` 结构体中,而不是把 `@TwelveOrLess` 作为特性写下来: + +``` +struct SmallRectangle { + private var _height = TwelveOrLess() + private var _width = TwelveOrLess() + var height: Int { + get { return _height.wrappedValue } + set { _height.wrappedValue = newValue } + } + var width: Int { + get { return _width.wrappedValue } + set { _width.wrappedValue = newValue } + } +} +``` + +`_height` 和 `_width` 属性存着这个属性包装器的一个实例,即 `TwelveOrLess`。`height` 和 `width` 的 getter 和 setter 把对 `wrappedValue` 属性的访问包装起来。 + +### 设置被包装属性的初始值 {#setting-initial-values-for-wrapped-properties} +上面例子中的代码通过在 `TwelveOrLess` 的定义中赋予 `number` 一个初始值来设置被包装属性的初始值。使用这个属性包装器的代码没法为被 `TwelveOrLess` 包装的属性指定其他初始值。举例来说,`SmallRectangle` 的定义没法给 `height` 或者 `width` 一个初始值。为了支持设定一个初始值或者其他自定义效果,属性包装器需要添加一个 + ## 全局变量和局部变量 {#global-and-local-variables} 计算属性和观察属性所描述的功能也可以用于*全局变量*和*局部变量*。全局变量是在函数、方法、闭包或任何类型之外定义的变量。局部变量是在函数、方法或闭包内部定义的变量。 From 5d3d15b836486ceb889bb3913aa473fbd9d734bc Mon Sep 17 00:00:00 2001 From: sunset wan Date: Sat, 12 Oct 2019 00:23:08 +0800 Subject: [PATCH 03/16] Translation in progress --- source/chapter2/10_Properties.md | 83 ++++++++++++++++++++++++++++++-- 1 file changed, 80 insertions(+), 3 deletions(-) diff --git a/source/chapter2/10_Properties.md b/source/chapter2/10_Properties.md index e70695a0..ef43bd07 100755 --- a/source/chapter2/10_Properties.md +++ b/source/chapter2/10_Properties.md @@ -346,11 +346,88 @@ struct SmallRectangle { `_height` 和 `_width` 属性存着这个属性包装器的一个实例,即 `TwelveOrLess`。`height` 和 `width` 的 getter 和 setter 把对 `wrappedValue` 属性的访问包装起来。 ### 设置被包装属性的初始值 {#setting-initial-values-for-wrapped-properties} -上面例子中的代码通过在 `TwelveOrLess` 的定义中赋予 `number` 一个初始值来设置被包装属性的初始值。使用这个属性包装器的代码没法为被 `TwelveOrLess` 包装的属性指定其他初始值。举例来说,`SmallRectangle` 的定义没法给 `height` 或者 `width` 一个初始值。为了支持设定一个初始值或者其他自定义效果,属性包装器需要添加一个 +上面例子中的代码通过在 `TwelveOrLess` 的定义中赋予 `number` 一个初始值来设置被包装属性的初始值。使用这个属性包装器的代码没法为被 `TwelveOrLess` 包装的属性指定其他初始值。举例来说,`SmallRectangle` 的定义没法给 `height` 或者 `width` 一个初始值。为了支持设定一个初始值或者其他自定义操作,属性包装器需要添加一个构造器。这是 `TwelveOrLess` 的扩展版本,称为 `SmallNumber`。`SmallNumber` 定义了能设置被包装的值和最大值的构造器: + + +``` +@propertyWrapper +struct SmallNumber { + private var maximum: Int + private var number: Int + + var wrappedValue: Int { + get { return number } + set { number = min(newValue, maximum) } + } + + init() { + maximum = 12 + number = 0 + } + init(wrappedValue: Int) { + maximum = 12 + number = min(wrappedValue, maximum) + } + init(wrappedValue: Int, maximum: Int) { + self.maximum = maximum + number = min(wrappedValue, maximum) + } +} +``` + +`SmallNumber` 的定义包括三个构造器——init()、init(wrappedValue:) 和 init(wrappedValue:maximum:)——下面的示例使用这三个构造器来设置被包装值和最大值。有关构造过程和构造器语法的更多信息,请参考 [构造过程](./14_Initialization.md)。 + +当你把包装器应用于属性且你没有设定初始值时,Swift 使用 `init()` 构造器来设置包装器。举个例子: + +``` +struct ZeroRectangle { + @SmallNumber var height: Int + @SmallNumber var width: Int +} + +var zeroRectangle = ZeroRectangle() +print(zeroRectangle.height, zeroRectangle.width) +// 打印 "0 0" +``` + +调用 `SmallNumber()` 来创建包装 `height` 和 `width` 的 `SmallNumber` 的实例。构造器内部的代码使用默认值 0 和 12 设置初始的被包装值和初始的最大值。像之前使用在 `SmallRectangle` 中使用 `TwelveOrLess` 的例子,这个属性包装器仍然提供所有的初始值。与这个例子不同的是,`SmallNumber` 也支持把编写这些初始值作为声明属性的一部分。 + +当你为属性指定初始值时,Swift 使用 `init(wrappedValue:)` 构造器来设置包装器。举个例子: + +``` +struct UnitRectangle { + @SmallNumber var height: Int = 1 + @SmallNumber var width: Int = 1 +} + +var unitRectangle = UnitRectangle() +print(unitRectangle.height, unitRectangle.width) +// 打印 "1 1" +``` + +当你对一个被包装的属性写下 `= 1` 时,这被转换为调用 `init(wrappedValue:)` 构造器。调用 `SmallNumber(wrappedValue: 1)`来创建包装 `height` 和 `width` 的 `SmallNumber` 的实例。构造器使用此处指定的被包装值,且使用的默认最大值为 12。 + +当你在自定义特性后面把实参写在括号里时,Swift 使用接受这些实参的构造器来设置包装器。举例来说,如果你提供初始值和最大值,Swift 使用 `init(wrappedValue:maximum:)` 构造器: + +``` +struct NarrowRectangle { + @SmallNumber(wrappedValue: 2, maximum: 5) var height: Int + @SmallNumber(wrappedValue: 3, maximum: 4) var width: Int +} + +var narrowRectangle = NarrowRectangle() +print(narrowRectangle.height, narrowRectangle.width) +// 打印 "2 3" + +narrowRectangle.height = 100 +narrowRectangle.width = 100 +print(narrowRectangle.height, narrowRectangle.width) +// 打印 "5 4" +``` + ## 全局变量和局部变量 {#global-and-local-variables} - -计算属性和观察属性所描述的功能也可以用于*全局变量*和*局部变量*。全局变量是在函数、方法、闭包或任何类型之外定义的变量。局部变量是在函数、方法或闭包内部定义的变量。 +计算属性和观察属性所描述的功能也可以用于全局变量和局部变量。全局变量是在函数、方法、闭包或任何类型之外定义的变量。局部变量是在函数、方法或闭包内部定义的变量。 前面章节提到的全局或局部变量都属于*存储型变量*,跟存储属性类似,它为特定类型的值提供存储空间,并允许读取和写入。 From b0a9b63e1f3d43a7d3d9ce3eed212101c6751191 Mon Sep 17 00:00:00 2001 From: sunset wan Date: Sun, 20 Oct 2019 16:52:28 +0800 Subject: [PATCH 04/16] Translation in progress --- source/chapter2/10_Properties.md | 94 ++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) diff --git a/source/chapter2/10_Properties.md b/source/chapter2/10_Properties.md index ef43bd07..97b94b29 100755 --- a/source/chapter2/10_Properties.md +++ b/source/chapter2/10_Properties.md @@ -425,6 +425,100 @@ print(narrowRectangle.height, narrowRectangle.width) // 打印 "5 4" ``` +调用 `SmallNumber(wrappedValue: 2, maximum: 5)` 来创建包装 `height` 的 `SmallNumber` 的一个实例。调用 `SmallNumber(wrappedValue: 3, maximum: 4)` 来创建包装 `width` 的 `SmallNumber` 的一个实例。 + +通过将实参包含到属性包装器中,你可以设置包装器的初始状态,或者在创建包装器时传递其他的选项。这种语法是使用属性包装器最通用的方法。你可以为这个属性提供任何所需的实参,且它们将被传递给构造器。 + +当包含属性包装器实参时,你也可以使用赋值来指定初始值。Swift 将赋值视为wrappedValue 参数,且使用接受被包含的实参的构造器。举个例子: + +``` +struct MixedRectangle { + @SmallNumber var height: Int = 1 + @SmallNumber(maximum: 9) var width: Int = 2 +} + +var mixedRectangle = MixedRectangle() +print(mixedRectangle.height) +// 打印 "1" + +mixedRectangle.height = 20 +print(mixedRectangle.height) +// 打印 "12" +``` + +调用 `SmallNumber(wrappedValue: 1)` 来创建包装 `height` 的 `SmallNumber` 的一个实例,这个实例使用默认最大值 12。调用 `SmallNumber(wrappedValue: 2, maximum: 9)` 来创建包装 `width` 的 `SmallNumber` 的一个实例。 + +### 待定 {#projecting-a-value-from-a-property-wrapper} +除了被包装的值,属性包装器可以通过定义 projected value 来暴露出其他功能。举个例子,管理对数据库的访问的属性包装器可以在它的 projectedValue 上暴露出 `flushDatabaseConnection()` 方法。除了以货币符号($)开头,projectedValue 的名称和被包装的值是一样的。因为你的代码不能够定义以 $ 开头的属性,所以 projectedValue 从不与你定义的属性有冲突。 + +在之前 `SmallNumber` 的例子中,如果你尝试把这个属性设置为一个很大很大的数值,属性包装器会在存储这个数值之前调整这个数值。以下的代码把 projectedValue 添加到 `SmallNumber` 结构体中来追踪在存储新值之前属性包装器是否为这个属性调整了新值。 + + +``` +@propertyWrapper +struct SmallNumber { + private var number = 0 + var projectedValue = false + var wrappedValue: Int { + get { return number } + set { + if newValue > 12 { + number = 12 + projectedValue = true + } else { + number = newValue + projectedValue = false + } + } + } +} +struct SomeStructure { + @SmallNumber var someNumber: Int +} +var someStructure = SomeStructure() + +someStructure.someNumber = 4 +print(someStructure.$someNumber) +// 打印 "false" + +someStructure.someNumber = 55 +print(someStructure.$someNumber) +// 打印 "true" +``` + +写下 `s.$someNumber` 即可访问包装器的 wrappedValue。在存储一个比较小的数值,如 4 ,`s.$someNumber` 的值为 `false`。但是,在尝试存储一个较大的数值,如 55 ,projectedValue 的值变为 `true`。 + +属性包装器可以返回任何类型的值作为它的 projectedValue。在这个例子里,属性包装器暴露出一条信息:那个数值是否被调整过,所以它暴露出布尔型值来作为它的 projectedValue。需要暴露出更多信息的包装器可以返回其他数据类型的实例,或者可以返回自身来暴露出包装器的实例,并把其作为它的 projectedValue。 + +当从类型的一部分代码中访问 projectedValue,例如属性 getter 或者实例方法,你可以在属性名称之前省略 `self.`,就像访问其他属性一样。以下示例中的代码将包装器的 `height` 和 `width` 的 projectedValue 称为 `$height` 和 `$width`: + +``` +enum Size { + case small, large +} + +struct SizedRectangle { + @SmallNumber var height: Int + @SmallNumber var width: Int + + mutating func resize(to size: Size) -> Bool { + switch size { + case .small: + height = 10 + width = 20 + case .large: + height = 100 + width = 100 + } + return $height || $width + } +} +``` + +因为属性包装器语法只是具有 getter 和 setter 的属性的语法糖,所以访问 `height` 和 `width` 的行为与访问任何其他属性的行为相同。举个例子,`resize(to:)` 中的代码使用它们的属性包装器来访问 `height` 和 `width`。如果调用 `resize(to: .large)`,`.large` 的 switch case 分支语句把矩形的高度和宽度设置为 100。属性包装器防止这些属性的值大于 12,且把 projectedValue 设置成为 `true` 来记下它调整过这些值的事实。在 `resize(to:)` 的最后,返回语句检查 `$height` 和 `$width` 来确认是否属性包装器调整过 `height` 或 `width`。 + + + ## 全局变量和局部变量 {#global-and-local-variables} 计算属性和观察属性所描述的功能也可以用于全局变量和局部变量。全局变量是在函数、方法、闭包或任何类型之外定义的变量。局部变量是在函数、方法或闭包内部定义的变量。 From 7656143f00153e241ee0bacd332f044a6bb9311f Mon Sep 17 00:00:00 2001 From: sunset wan Date: Sun, 27 Oct 2019 17:02:31 +0800 Subject: [PATCH 05/16] Finish translation of `Property Wrappers` Section --- README.md | 156 ++++++++++++++++--------------- source/chapter2/10_Properties.md | 30 +++--- 2 files changed, 94 insertions(+), 92 deletions(-) diff --git a/README.md b/README.md index ea3209b5..d2c770a6 100755 --- a/README.md +++ b/README.md @@ -55,83 +55,85 @@ diff 操作如下: 翻译术语的时候请参考这个对照表: -| 术语 | 备选翻译 | -| --- | --- | -| property wrapper | 属性包装器([翻译相关讨论](https://github.com/SwiftGGTeam/the-swift-programming-language-in-chinese/issues/982#issuecomment-536244784)) | -| argument | 实参 | -| parameter | 形参 | -| variadic parameters| 可变参数 | -| associated type | 关联类型 | -| range | 区间 | -| type property | 类型属性 | -| unary operator | 一元运算符 | -| binary operator | 二元运算符 | -| ternary operator | 三元运算符 | -| labeled statement | 具名语句 | -| conform protocol | 遵循协议 | -| availability-condition | 可用性条件 | -| fallthrough | 贯穿 | -| branch statement | 分支语句 | -| control transfer statement | 控制传递语句 | -| type annotation | 类型注解 | -| type identifier | 类型标识符 | -| metatype type | 元类型 | -| protocol composition type | 复合协议类型 | -| associated value | 关联值 | -| raw value | 原始值 | -| computed property | 计算属性 | -| stored property | 存储属性 | -| operator | 运算符 | -| playground | 不翻译 | -| array | 数组 | -| dictionary | 字典 | -| list | 列表 | -| statement | 语句 | -| expression | 表达式 | -| optional | 可选 | -| implicitly unwrapped optional | 隐式解包可选值 | -| optional binding | 可选绑定 | -| optional chaining | 可选链 | -| collection | 集合 | -| convention | 约定 | -| iterate | 迭代 | -| nest | 嵌套 | -| inheritance | 继承 | -| override | 重写 | -| base class | 基类 | -| designated initializer | 指定构造器 | -| convenience initializer | 便利构造器 | -| automatic reference counting | 自动引用计数 | -| type inference | 类型推断 | -| type casting | 类型转换 | -| unwrapped | 解包 | -| wrapped | 包装 | -| note | 注意 | -| closure | 闭包 | -| tuple | 元组 | -| first-class | 一等 | -| deinitializer | 析构器 | -| initializer | 构造器 | -| initialization | 构造过程 | -| deinitialization | 析构过程 | -| getter | 不翻译 | -| setter | 不翻译 | -| subscript | 下标 | -| property | 属性 | -| attribute | 特性或者属性,根据上下文 | -| method | 方法 | -| enumeration | 枚举 | -| structure | 结构体 | -| protocol | 协议 | -| extension | 扩展 | -| generic | 泛型 | -| literal value | 字面量 | -| alias | 别名 | -| assertion | 断言 | -| conditional compilation | 条件编译 | -| opaque type | 不透明类型 | -| function | 函数 | -| runtime | 运行时 | +| 术语 | 备选翻译 | +|-------------------------------|-----------------------------------------------------------------------------------------------------------------------------| +| property wrapper | 属性包装器([翻译相关讨论](https://github.com/SwiftGGTeam/the-swift-programming-language-in-chinese/issues/982#issuecomment-536244784)) | +| projected value | 被呈现值 | +| wrapped value | 被包装值 | +| argument | 实参 | +| parameter | 形参 | +| variadic parameters | 可变参数 | +| associated type | 关联类型 | +| range | 区间 | +| type property | 类型属性 | +| unary operator | 一元运算符 | +| binary operator | 二元运算符 | +| ternary operator | 三元运算符 | +| labeled statement | 具名语句 | +| conform protocol | 遵循协议 | +| availability-condition | 可用性条件 | +| fallthrough | 贯穿 | +| branch statement | 分支语句 | +| control transfer statement | 控制传递语句 | +| type annotation | 类型注解 | +| type identifier | 类型标识符 | +| metatype type | 元类型 | +| protocol composition type | 复合协议类型 | +| associated value | 关联值 | +| raw value | 原始值 | +| computed property | 计算属性 | +| stored property | 存储属性 | +| operator | 运算符 | +| playground | 不翻译 | +| array | 数组 | +| dictionary | 字典 | +| list | 列表 | +| statement | 语句 | +| expression | 表达式 | +| optional | 可选 | +| implicitly unwrapped optional | 隐式解包可选值 | +| optional binding | 可选绑定 | +| optional chaining | 可选链 | +| collection | 集合 | +| convention | 约定 | +| iterate | 迭代 | +| nest | 嵌套 | +| inheritance | 继承 | +| override | 重写 | +| base class | 基类 | +| designated initializer | 指定构造器 | +| convenience initializer | 便利构造器 | +| automatic reference counting | 自动引用计数 | +| type inference | 类型推断 | +| type casting | 类型转换 | +| unwrapped | 解包 | +| wrapped | 包装 | +| note | 注意 | +| closure | 闭包 | +| tuple | 元组 | +| first-class | 一等 | +| deinitializer | 析构器 | +| initializer | 构造器 | +| initialization | 构造过程 | +| deinitialization | 析构过程 | +| getter | 不翻译 | +| setter | 不翻译 | +| subscript | 下标 | +| property | 属性 | +| attribute | 特性或者属性,根据上下文 | +| method | 方法 | +| enumeration | 枚举 | +| structure | 结构体 | +| protocol | 协议 | +| extension | 扩展 | +| generic | 泛型 | +| literal value | 字面量 | +| alias | 别名 | +| assertion | 断言 | +| conditional compilation | 条件编译 | +| opaque type | 不透明类型 | +| function | 函数 | +| runtime | 运行时 | # 贡献者 diff --git a/source/chapter2/10_Properties.md b/source/chapter2/10_Properties.md index 97b94b29..594ffd83 100755 --- a/source/chapter2/10_Properties.md +++ b/source/chapter2/10_Properties.md @@ -283,9 +283,9 @@ stepCounter.totalSteps = 896 > 如果将带有观察器的属性通过 in-out 方式传入函数,`willSet` 和 `didSet` 也会调用。这是因为 in-out 参数采用了拷入拷出内存模式:即在函数内部使用的是参数的 copy,函数结束后,又对参数重新赋值。关于 in-out 参数详细的介绍,请参考 [输入输出参数](../chapter3/05_Declarations.html#in-out_parameters) ## 属性包装器 {#property-wrappers} -属性包装器在管理一个属性是如何存储的代码和定义一个属性的代码之间添加了一层分隔层。举例来说,如果你有一些提供线程安全性检查或者在数据库中存储它们基本数据的属性,你必须对每个属性都添加这段代码。当使用属性包装器时,你只需在定义属性包装器时编写一次管理代码,然后通过把它应用到多个属性上的方式来复用那段管理代码。 +属性包装器在一段管理属性是如何存储的代码和一段定义属性的代码之间添加了一个分隔层。举例来说,如果你有一些提供线程安全性检查的属性或者在数据库中存储它们基本数据的属性,你必须对每个属性都添加这段代码。当使用属性包装器时,你只需在定义属性包装器时编写一次管理代码,然后通过把它应用到多个属性上的方式来复用那段管理代码。 -为了定义一个属性包装器,你需要创建一个定义 `wrappedValue` 属性的结构体、枚举或者类。在下面的代码中,`TwelveOrLess` 结构体确保它包装的值始终包含小于等于12的数字。如果你要求它存储一个更大的数字,它则会存储 12 这个数字。 +为了定义一个属性包装器,你需要创建一个定义 `wrappedValue` 属性的结构体、枚举或者类。在下面的代码中,`TwelveOrLess` 结构体确保它包装的值始终是小于等于 12 的数字。如果要求它存储一个更大的数字,它则会存储 12 这个数字。 ``` @propertyWrapper @@ -298,12 +298,12 @@ struct TwelveOrLess { } ``` -这个 setter 确保新值小于 12,且这个 getter 返回被存储的值。 +这个 setter 确保新值小于 12,而且返回被存储的值。 > 注意 > > 在上面例子中对 `number` 的声明把这个变量标记为 `private`,这使得 `number` 仅在 `TwelveOrLess` 的实现中使用。写在其他地方的代码通过使用 `wrappedValue` 的 getter 和 setter 来获取这个值,且不能直接使用 `number`。有关 `private` 的更多信息,请参考 [访问控制](./25_Access_Control.md) -通过在属性之前写上包装器的名称的方式,你可以把一个包装器应用到一个属性上去,这个包装器的名称作为这个属性的特性。这里有一个存储一个很小的矩形的结构体。这个结构体使用了同样的(相当随意的)由 `TwelveOrLess` 属性包装器实现的“小”的定义。 +通过在属性之前写上包装器名称的方式,你可以把一个包装器应用到一个属性上去,这个包装器的名称作为这个属性的特性。这里有个存储一个很小的矩形的结构体。这个结构体使用了同样的(相当随意的)由 `TwelveOrLess` 属性包装器实现的“小”的定义。 ``` struct SmallRectangle { @@ -326,7 +326,7 @@ print(rectangle.height) `height` 和 `width` 属性从 `TwelveOrLess` 的定义中获取它们的初始值。该定义把 `TwelveOrLess.number` 设置为 0。把数字 10 存进 `rectangle.height` 中的操作能成功,是因为数字 10 很小。尝试存储 24 的操作实际上存储的值为 12,这是因为对于这个属性的 setter 的规则来说,24 太大了。 -当你把一个包装器应用到一个属性上时,编译器将合成为包装器提供存储空间的代码和提供通过包装程序访问属性的代码。(属性包装器负责存储被包装的值,所以没有为此合成的代码。)不利用这个特性语法的情况下,你可以写出使用属性包装器行为的代码。举例来说,这是先前代码清单中的 `SmallRectangle` 的一个版本。这个版本将其属性明确地包装在 `TwelveOrLess` 结构体中,而不是把 `@TwelveOrLess` 作为特性写下来: +当你把一个包装器应用到一个属性上时,编译器将合成为包装器提供存储空间的代码和提供通过包装程序访问属性的代码。(属性包装器负责存储被包装值,所以没有为此合成的代码。)不利用这个特性语法的情况下,你可以写出使用属性包装器行为的代码。举例来说,这是先前代码清单中的 `SmallRectangle` 的一个版本。这个版本将其属性明确地包装在 `TwelveOrLess` 结构体中,而不是把 `@TwelveOrLess` 作为特性写下来: ``` struct SmallRectangle { @@ -346,7 +346,7 @@ struct SmallRectangle { `_height` 和 `_width` 属性存着这个属性包装器的一个实例,即 `TwelveOrLess`。`height` 和 `width` 的 getter 和 setter 把对 `wrappedValue` 属性的访问包装起来。 ### 设置被包装属性的初始值 {#setting-initial-values-for-wrapped-properties} -上面例子中的代码通过在 `TwelveOrLess` 的定义中赋予 `number` 一个初始值来设置被包装属性的初始值。使用这个属性包装器的代码没法为被 `TwelveOrLess` 包装的属性指定其他初始值。举例来说,`SmallRectangle` 的定义没法给 `height` 或者 `width` 一个初始值。为了支持设定一个初始值或者其他自定义操作,属性包装器需要添加一个构造器。这是 `TwelveOrLess` 的扩展版本,称为 `SmallNumber`。`SmallNumber` 定义了能设置被包装的值和最大值的构造器: +上面例子中的代码通过在 `TwelveOrLess` 的定义中赋予 `number` 一个初始值来设置被包装属性的初始值。使用这个属性包装器的代码没法为被 `TwelveOrLess` 包装的属性指定其他初始值。举例来说,`SmallRectangle` 的定义没法给 `height` 或者 `width` 一个初始值。为了支持设定一个初始值或者其他自定义操作,属性包装器需要添加一个构造器。这是 `TwelveOrLess` 的扩展版本,称为 `SmallNumber`。`SmallNumber` 定义了能设置被包装值和最大值的构造器: ``` @@ -375,9 +375,9 @@ struct SmallNumber { } ``` -`SmallNumber` 的定义包括三个构造器——init()、init(wrappedValue:) 和 init(wrappedValue:maximum:)——下面的示例使用这三个构造器来设置被包装值和最大值。有关构造过程和构造器语法的更多信息,请参考 [构造过程](./14_Initialization.md)。 +`SmallNumber` 的定义包括三个构造器——`init()`、`init(wrappedValue:)` 和 `init(wrappedValue:maximum:)`——下面的示例使用这三个构造器来设置被包装值和最大值。有关构造过程和构造器语法的更多信息,请参考 [构造过程](./14_Initialization.md)。 -当你把包装器应用于属性且你没有设定初始值时,Swift 使用 `init()` 构造器来设置包装器。举个例子: +当你把包装器应用于属性且没有设定初始值时,Swift 使用 `init()` 构造器来设置包装器。举个例子: ``` struct ZeroRectangle { @@ -448,10 +448,10 @@ print(mixedRectangle.height) 调用 `SmallNumber(wrappedValue: 1)` 来创建包装 `height` 的 `SmallNumber` 的一个实例,这个实例使用默认最大值 12。调用 `SmallNumber(wrappedValue: 2, maximum: 9)` 来创建包装 `width` 的 `SmallNumber` 的一个实例。 -### 待定 {#projecting-a-value-from-a-property-wrapper} -除了被包装的值,属性包装器可以通过定义 projected value 来暴露出其他功能。举个例子,管理对数据库的访问的属性包装器可以在它的 projectedValue 上暴露出 `flushDatabaseConnection()` 方法。除了以货币符号($)开头,projectedValue 的名称和被包装的值是一样的。因为你的代码不能够定义以 $ 开头的属性,所以 projectedValue 从不与你定义的属性有冲突。 +### 从属性包装器中呈现一个值 {#projecting-a-value-from-a-property-wrapper} +除了被包装值,属性包装器可以通过定义被呈现值暴露出其他功能。举个例子,管理对数据库的访问的属性包装器可以在它的被呈现值上暴露出 `flushDatabaseConnection()` 方法。除了以货币符号(\$)开头,被呈现值的名称和被包装值是一样的。因为你的代码不能够定义以 $ 开头的属性,所以被呈现值 从不与你定义的属性有冲突。 -在之前 `SmallNumber` 的例子中,如果你尝试把这个属性设置为一个很大很大的数值,属性包装器会在存储这个数值之前调整这个数值。以下的代码把 projectedValue 添加到 `SmallNumber` 结构体中来追踪在存储新值之前属性包装器是否为这个属性调整了新值。 +在之前 `SmallNumber` 的例子中,如果你尝试把这个属性设置为一个很大的数值,属性包装器会在存储这个数值之前调整这个数值。以下的代码把被呈现值添加到 `SmallNumber` 结构体中来追踪在存储新值之前属性包装器是否为这个属性调整了新值。 ``` @@ -486,11 +486,11 @@ print(someStructure.$someNumber) // 打印 "true" ``` -写下 `s.$someNumber` 即可访问包装器的 wrappedValue。在存储一个比较小的数值,如 4 ,`s.$someNumber` 的值为 `false`。但是,在尝试存储一个较大的数值,如 55 ,projectedValue 的值变为 `true`。 +写下 `s.$someNumber` 即可访问包装器的被呈现值。在存储一个比较小的数值,如 4 ,`s.$someNumber` 的值为 `false`。但是,在尝试存储一个较大的数值,如 55 ,被呈现值变为 `true`。 -属性包装器可以返回任何类型的值作为它的 projectedValue。在这个例子里,属性包装器暴露出一条信息:那个数值是否被调整过,所以它暴露出布尔型值来作为它的 projectedValue。需要暴露出更多信息的包装器可以返回其他数据类型的实例,或者可以返回自身来暴露出包装器的实例,并把其作为它的 projectedValue。 +属性包装器可以返回任何类型的值作为它的被呈现值。在这个例子里,属性包装器暴露出一条信息:那个数值是否被调整过,所以它暴露出布尔型值来作为它的被呈现值。需要暴露出更多信息的包装器可以返回其他数据类型的实例,或者可以返回自身来暴露出包装器的实例,并把其作为它的被呈现值。 -当从类型的一部分代码中访问 projectedValue,例如属性 getter 或者实例方法,你可以在属性名称之前省略 `self.`,就像访问其他属性一样。以下示例中的代码将包装器的 `height` 和 `width` 的 projectedValue 称为 `$height` 和 `$width`: +当从类型的一部分代码中访问被呈现值,例如属性 getter 或实例方法,你可以在属性名称之前省略 `self.`,就像访问其他属性一样。以下示例中的代码将包装器的 `height` 和 `width` 的被呈现值称为 `$height` 和 `$width`: ``` enum Size { @@ -515,7 +515,7 @@ struct SizedRectangle { } ``` -因为属性包装器语法只是具有 getter 和 setter 的属性的语法糖,所以访问 `height` 和 `width` 的行为与访问任何其他属性的行为相同。举个例子,`resize(to:)` 中的代码使用它们的属性包装器来访问 `height` 和 `width`。如果调用 `resize(to: .large)`,`.large` 的 switch case 分支语句把矩形的高度和宽度设置为 100。属性包装器防止这些属性的值大于 12,且把 projectedValue 设置成为 `true` 来记下它调整过这些值的事实。在 `resize(to:)` 的最后,返回语句检查 `$height` 和 `$width` 来确认是否属性包装器调整过 `height` 或 `width`。 +因为属性包装器语法只是具有 getter 和 setter 的属性的语法糖,所以访问 `height` 和 `width` 的行为与访问任何其他属性的行为相同。举个例子,`resize(to:)` 中的代码使用它们的属性包装器来访问 `height` 和 `width`。如果调用 `resize(to: .large)`,`.large` 的 switch case 分支语句把矩形的高度和宽度设置为 100。属性包装器防止这些属性的值大于 12,且把被呈现值设置成为 `true` 来记下它调整过这些值的事实。在 `resize(to:)` 的最后,返回语句检查 `$height` 和 `$width` 来确认是否属性包装器调整过 `height` 或 `width`。 From 32fa806e77ca897db275832a974479164fecf039 Mon Sep 17 00:00:00 2001 From: sunset wan Date: Sat, 2 Nov 2019 22:37:36 +0800 Subject: [PATCH 06/16] Keep the style of the old README.md --- README.md | 160 +++++++++++++++++++++++++++--------------------------- 1 file changed, 80 insertions(+), 80 deletions(-) diff --git a/README.md b/README.md index d2c770a6..363fe075 100755 --- a/README.md +++ b/README.md @@ -55,85 +55,85 @@ diff 操作如下: 翻译术语的时候请参考这个对照表: -| 术语 | 备选翻译 | -|-------------------------------|-----------------------------------------------------------------------------------------------------------------------------| -| property wrapper | 属性包装器([翻译相关讨论](https://github.com/SwiftGGTeam/the-swift-programming-language-in-chinese/issues/982#issuecomment-536244784)) | -| projected value | 被呈现值 | -| wrapped value | 被包装值 | -| argument | 实参 | -| parameter | 形参 | -| variadic parameters | 可变参数 | -| associated type | 关联类型 | -| range | 区间 | -| type property | 类型属性 | -| unary operator | 一元运算符 | -| binary operator | 二元运算符 | -| ternary operator | 三元运算符 | -| labeled statement | 具名语句 | -| conform protocol | 遵循协议 | -| availability-condition | 可用性条件 | -| fallthrough | 贯穿 | -| branch statement | 分支语句 | -| control transfer statement | 控制传递语句 | -| type annotation | 类型注解 | -| type identifier | 类型标识符 | -| metatype type | 元类型 | -| protocol composition type | 复合协议类型 | -| associated value | 关联值 | -| raw value | 原始值 | -| computed property | 计算属性 | -| stored property | 存储属性 | -| operator | 运算符 | -| playground | 不翻译 | -| array | 数组 | -| dictionary | 字典 | -| list | 列表 | -| statement | 语句 | -| expression | 表达式 | -| optional | 可选 | -| implicitly unwrapped optional | 隐式解包可选值 | -| optional binding | 可选绑定 | -| optional chaining | 可选链 | -| collection | 集合 | -| convention | 约定 | -| iterate | 迭代 | -| nest | 嵌套 | -| inheritance | 继承 | -| override | 重写 | -| base class | 基类 | -| designated initializer | 指定构造器 | -| convenience initializer | 便利构造器 | -| automatic reference counting | 自动引用计数 | -| type inference | 类型推断 | -| type casting | 类型转换 | -| unwrapped | 解包 | -| wrapped | 包装 | -| note | 注意 | -| closure | 闭包 | -| tuple | 元组 | -| first-class | 一等 | -| deinitializer | 析构器 | -| initializer | 构造器 | -| initialization | 构造过程 | -| deinitialization | 析构过程 | -| getter | 不翻译 | -| setter | 不翻译 | -| subscript | 下标 | -| property | 属性 | -| attribute | 特性或者属性,根据上下文 | -| method | 方法 | -| enumeration | 枚举 | -| structure | 结构体 | -| protocol | 协议 | -| extension | 扩展 | -| generic | 泛型 | -| literal value | 字面量 | -| alias | 别名 | -| assertion | 断言 | -| conditional compilation | 条件编译 | -| opaque type | 不透明类型 | -| function | 函数 | -| runtime | 运行时 | +| 术语 | 备选翻译 | +| --- | --- | +| property wrapper | 属性包装器([翻译相关讨论](https://github.com/SwiftGGTeam/the-swift-programming-language-in-chinese/issues/982#issuecomment-536244784)) | +| projected value | 被呈现值 | +| wrapped value | 被包装值 | +| argument | 实参 | +| parameter | 形参 | +| variadic parameters| 可变参数 | +| associated type | 关联类型 | +| range | 区间 | +| type property | 类型属性 | +| unary operator | 一元运算符 | +| binary operator | 二元运算符 | +| ternary operator | 三元运算符 | +| labeled statement | 具名语句 | +| conform protocol | 遵循协议 | +| availability-condition | 可用性条件 | +| fallthrough | 贯穿 | +| branch statement | 分支语句 | +| control transfer statement | 控制传递语句 | +| type annotation | 类型注解 | +| type identifier | 类型标识符 | +| metatype type | 元类型 | +| protocol composition type | 复合协议类型 | +| associated value | 关联值 | +| raw value | 原始值 | +| computed property | 计算属性 | +| stored property | 存储属性 | +| operator | 运算符 | +| playground | 不翻译 | +| array | 数组 | +| dictionary | 字典 | +| list | 列表 | +| statement | 语句 | +| expression | 表达式 | +| optional | 可选 | +| implicitly unwrapped optional | 隐式解包可选值 | +| optional binding | 可选绑定 | +| optional chaining | 可选链 | +| collection | 集合 | +| convention | 约定 | +| iterate | 迭代 | +| nest | 嵌套 | +| inheritance | 继承 | +| override | 重写 | +| base class | 基类 | +| designated initializer | 指定构造器 | +| convenience initializer | 便利构造器 | +| automatic reference counting | 自动引用计数 | +| type inference | 类型推断 | +| type casting | 类型转换 | +| unwrapped | 解包 | +| wrapped | 包装 | +| note | 注意 | +| closure | 闭包 | +| tuple | 元组 | +| first-class | 一等 | +| deinitializer | 析构器 | +| initializer | 构造器 | +| initialization | 构造过程 | +| deinitialization | 析构过程 | +| getter | 不翻译 | +| setter | 不翻译 | +| subscript | 下标 | +| property | 属性 | +| attribute | 特性或者属性,根据上下文 | +| method | 方法 | +| enumeration | 枚举 | +| structure | 结构体 | +| protocol | 协议 | +| extension | 扩展 | +| generic | 泛型 | +| literal value | 字面量 | +| alias | 别名 | +| assertion | 断言 | +| conditional compilation | 条件编译 | +| opaque type | 不透明类型 | +| function | 函数 | +| runtime | 运行时 | # 贡献者 @@ -142,4 +142,4 @@ diff 操作如下: # 协议 -和 [苹果官方文档](https://swift.org/documentation/) 协议一致:[Creative Commons Attribution 4.0 International (CC BY 4.0) License](https://creativecommons.org/licenses/by/4.0/)。 +和 [苹果官方文档](https://swift.org/documentation/) 协议一致:[Creative Commons Attribution 4.0 International (CC BY 4.0) License](https://creativecommons.org/licenses/by/4.0/)。 \ No newline at end of file From 9988f57550ac21687eee20fd40f4a18b4717e119 Mon Sep 17 00:00:00 2001 From: sunset wan Date: Sat, 2 Nov 2019 22:49:14 +0800 Subject: [PATCH 07/16] Refine translation --- source/chapter2/10_Properties.md | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/source/chapter2/10_Properties.md b/source/chapter2/10_Properties.md index 594ffd83..01aeec6d 100755 --- a/source/chapter2/10_Properties.md +++ b/source/chapter2/10_Properties.md @@ -7,12 +7,11 @@ 另外,还可以定义属性观察器来监控属性值的变化,以此来触发自定义的操作。属性观察器可以添加到类本身定义的存储属性上,也可以添加到从父类继承的属性上。 你也可以利用属性包装器来复用多个属性的 getter 和 setter 中的代码。 - ## 存储属性 {#stored-properties} 简单来说,一个存储属性就是存储在特定类或结构体实例里的一个常量或变量。存储属性可以是*变量存储属性*(用关键字 `var` 定义),也可以是*常量存储属性*(用关键字 `let` 定义)。 -可以在定义存储属性的时候指定默认值,请参考 [默认构造器](./14_Initialization.md#default_initializers) 一节。也可以在构造过程中设置或修改存储属性的值,甚至修改常量存储属性的值,请参考 [构造过程中常量属性的修改](./14_Initialization.md#assigning_constant_properties_during_initialization) 一节。 +可以在定义存储属性的时候指定默认值,请参考 [默认构造器](./14_Initialization.md#default-initializers) 一节。也可以在构造过程中设置或修改存储属性的值,甚至修改常量存储属性的值,请参考 [构造过程中常量属性的修改](./14-Initialization.md#assigning-constant-properties-during-initialization) 一节。 下面的例子定义了一个名为 `FixedLengthRange` 的结构体,该结构体用于描述整数的区间,且这个范围值在被创建后不能被修改。 @@ -241,7 +240,7 @@ print("the volume of fourByFiveByTwo is \(fourByFiveByTwo.volume)") > > 在父类初始化方法调用之后,在子类构造器中给父类的属性赋值时,会调用父类属性的 `willSet` 和 `didSet` 观察器。而在父类初始化方法调用之前,给子类的属性赋值时不会调用子类属性的观察器。 > -> 有关构造器代理的更多信息,请参考 [值类型的构造器代理](./14_Initialization.md#initializer_delegation_for_value_types) 和 [类的构造器代理](./14_Initialization.md#initializer_delegation_for_class_types)。 +> 有关构造器代理的更多信息,请参考 [值类型的构造器代理](./14_Initialization.md#initializer-delegation-for-value-types) 和 [类的构造器代理](./14-Initialization.md#initializer-delegation-for-class-types)。 下面是一个 `willSet` 和 `didSet` 实际运用的例子,其中定义了一个名为 `StepCounter` 的类,用来统计一个人步行时的总步数。这个类可以跟计步器或其他日常锻炼的统计装置的输入数据配合使用。 @@ -280,7 +279,7 @@ stepCounter.totalSteps = 896 > 注意 > -> 如果将带有观察器的属性通过 in-out 方式传入函数,`willSet` 和 `didSet` 也会调用。这是因为 in-out 参数采用了拷入拷出内存模式:即在函数内部使用的是参数的 copy,函数结束后,又对参数重新赋值。关于 in-out 参数详细的介绍,请参考 [输入输出参数](../chapter3/05_Declarations.html#in-out_parameters) +> 如果将带有观察器的属性通过 in-out 方式传入函数,`willSet` 和 `didSet` 也会调用。这是因为 in-out 参数采用了拷入拷出内存模式:即在函数内部使用的是参数的 copy,函数结束后,又对参数重新赋值。关于 in-out 参数详细的介绍,请参考 [输入输出参数](../03_language_reference/05_Declarations.html#in-out-parameters)。 ## 属性包装器 {#property-wrappers} 属性包装器在一段管理属性是如何存储的代码和一段定义属性的代码之间添加了一个分隔层。举例来说,如果你有一些提供线程安全性检查的属性或者在数据库中存储它们基本数据的属性,你必须对每个属性都添加这段代码。当使用属性包装器时,你只需在定义属性包装器时编写一次管理代码,然后通过把它应用到多个属性上的方式来复用那段管理代码。 @@ -518,10 +517,9 @@ struct SizedRectangle { 因为属性包装器语法只是具有 getter 和 setter 的属性的语法糖,所以访问 `height` 和 `width` 的行为与访问任何其他属性的行为相同。举个例子,`resize(to:)` 中的代码使用它们的属性包装器来访问 `height` 和 `width`。如果调用 `resize(to: .large)`,`.large` 的 switch case 分支语句把矩形的高度和宽度设置为 100。属性包装器防止这些属性的值大于 12,且把被呈现值设置成为 `true` 来记下它调整过这些值的事实。在 `resize(to:)` 的最后,返回语句检查 `$height` 和 `$width` 来确认是否属性包装器调整过 `height` 或 `width`。 - - ## 全局变量和局部变量 {#global-and-local-variables} -计算属性和观察属性所描述的功能也可以用于全局变量和局部变量。全局变量是在函数、方法、闭包或任何类型之外定义的变量。局部变量是在函数、方法或闭包内部定义的变量。 + +计算属性和观察属性所描述的功能也可以用于*全局变量*和*局部变量*。全局变量是在函数、方法、闭包或任何类型之外定义的变量。局部变量是在函数、方法或闭包内部定义的变量。 前面章节提到的全局或局部变量都属于*存储型变量*,跟存储属性类似,它为特定类型的值提供存储空间,并允许读取和写入。 @@ -529,7 +527,7 @@ struct SizedRectangle { > 注意 > -> 全局的常量或变量都是延迟计算的,跟 [延时加载存储属性](#lazy_stored_properties) 相似,不同的地方在于,全局的常量或变量不需要标记 `lazy` 修饰符。 +> 全局的常量或变量都是延迟计算的,跟 [延时加载存储属性](#lazy-stored-properties) 相似,不同的地方在于,全局的常量或变量不需要标记 `lazy` 修饰符。 > > 局部范围的常量和变量从不延迟计算。 @@ -666,4 +664,4 @@ print(rightChannel.currentLevel) // 输出“10” print(AudioChannel.maxInputLevelForAllChannels) // 输出“10” -``` +``` \ No newline at end of file From 028268e7a6d69fcd1c3fdf2a2cc7ac583729b0e4 Mon Sep 17 00:00:00 2001 From: sunset wan Date: Sat, 9 Nov 2019 16:18:31 +0800 Subject: [PATCH 08/16] Refine the translation --- source/chapter2/10_Properties.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/source/chapter2/10_Properties.md b/source/chapter2/10_Properties.md index 01aeec6d..0ef3c2f4 100755 --- a/source/chapter2/10_Properties.md +++ b/source/chapter2/10_Properties.md @@ -282,9 +282,9 @@ stepCounter.totalSteps = 896 > 如果将带有观察器的属性通过 in-out 方式传入函数,`willSet` 和 `didSet` 也会调用。这是因为 in-out 参数采用了拷入拷出内存模式:即在函数内部使用的是参数的 copy,函数结束后,又对参数重新赋值。关于 in-out 参数详细的介绍,请参考 [输入输出参数](../03_language_reference/05_Declarations.html#in-out-parameters)。 ## 属性包装器 {#property-wrappers} -属性包装器在一段管理属性是如何存储的代码和一段定义属性的代码之间添加了一个分隔层。举例来说,如果你有一些提供线程安全性检查的属性或者在数据库中存储它们基本数据的属性,你必须对每个属性都添加这段代码。当使用属性包装器时,你只需在定义属性包装器时编写一次管理代码,然后通过把它应用到多个属性上的方式来复用那段管理代码。 +属性包装器在管理属性如何存储和定义属性的代码之间添加了一个分隔层。举例来说,如果你的属性需要线程安全性检查或者需要在数据库中存储它们的基本数据,那么必须给每个属性添加同样的逻辑代码。当使用属性包装器时,你只需在定义属性包装器时编写一次管理代码,然后应用到多个属性上来进行复用。 -为了定义一个属性包装器,你需要创建一个定义 `wrappedValue` 属性的结构体、枚举或者类。在下面的代码中,`TwelveOrLess` 结构体确保它包装的值始终是小于等于 12 的数字。如果要求它存储一个更大的数字,它则会存储 12 这个数字。 +定义一个属性包装器,你需要创建一个定义 `wrappedValue` 属性的结构体、枚举或者类。在下面的代码中,`TwelveOrLess` 结构体确保它包装的值始终是小于等于 12 的数字。如果要求它存储一个更大的数字,它则会存储 12 这个数字。 ``` @propertyWrapper @@ -300,9 +300,9 @@ struct TwelveOrLess { 这个 setter 确保新值小于 12,而且返回被存储的值。 > 注意 > -> 在上面例子中对 `number` 的声明把这个变量标记为 `private`,这使得 `number` 仅在 `TwelveOrLess` 的实现中使用。写在其他地方的代码通过使用 `wrappedValue` 的 getter 和 setter 来获取这个值,且不能直接使用 `number`。有关 `private` 的更多信息,请参考 [访问控制](./25_Access_Control.md) +> 上面例子以 `private` 的方式声明 `number` 变量,这使得 `number` 仅在 `TwelveOrLess` 的实现中使用。写在其他地方的代码通过使用 `wrappedValue` 的 getter 和 setter 来获取这个值,但不能直接使用 `number`。有关 `private` 的更多信息,请参考 [访问控制](./25_Access_Control.md) -通过在属性之前写上包装器名称的方式,你可以把一个包装器应用到一个属性上去,这个包装器的名称作为这个属性的特性。这里有个存储一个很小的矩形的结构体。这个结构体使用了同样的(相当随意的)由 `TwelveOrLess` 属性包装器实现的“小”的定义。 +通过在属性之前写上包装器名称作为特性的方式,你可以把一个包装器应用到一个属性上去。这里有个存储小矩形的结构体。通过 `TwelveOrLess` 属性包装器实现类似(挺随意的)对“小”的定义。 ``` struct SmallRectangle { @@ -325,7 +325,7 @@ print(rectangle.height) `height` 和 `width` 属性从 `TwelveOrLess` 的定义中获取它们的初始值。该定义把 `TwelveOrLess.number` 设置为 0。把数字 10 存进 `rectangle.height` 中的操作能成功,是因为数字 10 很小。尝试存储 24 的操作实际上存储的值为 12,这是因为对于这个属性的 setter 的规则来说,24 太大了。 -当你把一个包装器应用到一个属性上时,编译器将合成为包装器提供存储空间的代码和提供通过包装程序访问属性的代码。(属性包装器负责存储被包装值,所以没有为此合成的代码。)不利用这个特性语法的情况下,你可以写出使用属性包装器行为的代码。举例来说,这是先前代码清单中的 `SmallRectangle` 的一个版本。这个版本将其属性明确地包装在 `TwelveOrLess` 结构体中,而不是把 `@TwelveOrLess` 作为特性写下来: +当你把一个包装器应用到一个属性上时,编译器将合成提供包装器存储空间和通过包装器访问属性的代码。(属性包装器只负责存储被包装值,所以没有合成这些代码。)不利用这个特性语法的情况下,你可以写出使用属性包装器行为的代码。举例来说,这是先前代码清单中的 `SmallRectangle` 的另一个版本。这个版本将其属性明确地包装在 `TwelveOrLess` 结构体中,而不是把 `@TwelveOrLess` 作为特性写下来: ``` struct SmallRectangle { @@ -428,7 +428,7 @@ print(narrowRectangle.height, narrowRectangle.width) 通过将实参包含到属性包装器中,你可以设置包装器的初始状态,或者在创建包装器时传递其他的选项。这种语法是使用属性包装器最通用的方法。你可以为这个属性提供任何所需的实参,且它们将被传递给构造器。 -当包含属性包装器实参时,你也可以使用赋值来指定初始值。Swift 将赋值视为wrappedValue 参数,且使用接受被包含的实参的构造器。举个例子: +当包含属性包装器实参时,你也可以使用赋值来指定初始值。Swift 将赋值视为 `wrappedValue` 参数,且使用接受被包含的实参的构造器。举个例子: ``` struct MixedRectangle { @@ -448,7 +448,7 @@ print(mixedRectangle.height) 调用 `SmallNumber(wrappedValue: 1)` 来创建包装 `height` 的 `SmallNumber` 的一个实例,这个实例使用默认最大值 12。调用 `SmallNumber(wrappedValue: 2, maximum: 9)` 来创建包装 `width` 的 `SmallNumber` 的一个实例。 ### 从属性包装器中呈现一个值 {#projecting-a-value-from-a-property-wrapper} -除了被包装值,属性包装器可以通过定义被呈现值暴露出其他功能。举个例子,管理对数据库的访问的属性包装器可以在它的被呈现值上暴露出 `flushDatabaseConnection()` 方法。除了以货币符号(\$)开头,被呈现值的名称和被包装值是一样的。因为你的代码不能够定义以 $ 开头的属性,所以被呈现值 从不与你定义的属性有冲突。 +除了被包装值,属性包装器可以通过定义被呈现值暴露出其他功能。举个例子,管理对数据库的访问的属性包装器可以在它的被呈现值上暴露出 `flushDatabaseConnection()` 方法。除了以货币符号(\$)开头,被呈现值的名称和被包装值是一样的。因为你的代码不能够定义以 $ 开头的属性,所以被呈现值永远不会与你定义的属性有冲突。 在之前 `SmallNumber` 的例子中,如果你尝试把这个属性设置为一个很大的数值,属性包装器会在存储这个数值之前调整这个数值。以下的代码把被呈现值添加到 `SmallNumber` 结构体中来追踪在存储新值之前属性包装器是否为这个属性调整了新值。 @@ -485,11 +485,11 @@ print(someStructure.$someNumber) // 打印 "true" ``` -写下 `s.$someNumber` 即可访问包装器的被呈现值。在存储一个比较小的数值,如 4 ,`s.$someNumber` 的值为 `false`。但是,在尝试存储一个较大的数值,如 55 ,被呈现值变为 `true`。 +写下 `s.$someNumber` 即可访问包装器的被呈现值。在存储一个比较小的数值时,如 4 ,`s.$someNumber` 的值为 `false`。但是,在尝试存储一个较大的数值时,如 55 ,被呈现值变为 `true`。 -属性包装器可以返回任何类型的值作为它的被呈现值。在这个例子里,属性包装器暴露出一条信息:那个数值是否被调整过,所以它暴露出布尔型值来作为它的被呈现值。需要暴露出更多信息的包装器可以返回其他数据类型的实例,或者可以返回自身来暴露出包装器的实例,并把其作为它的被呈现值。 +属性包装器可以返回任何类型的值作为它的被呈现值。在这个例子里,属性包装器要暴露的信息是:那个数值是否被调整过,所以它暴露出布尔型值来作为它的被呈现值。需要暴露出更多信息的包装器可以返回其他数据类型的实例,或者可以返回自身来暴露出包装器的实例,并把其作为它的被呈现值。 -当从类型的一部分代码中访问被呈现值,例如属性 getter 或实例方法,你可以在属性名称之前省略 `self.`,就像访问其他属性一样。以下示例中的代码将包装器的 `height` 和 `width` 的被呈现值称为 `$height` 和 `$width`: +当从类型的一部分代码中访问被呈现值,例如属性 getter 或实例方法,你可以在属性名称之前省略 `self.`,就像访问其他属性一样。以下示例中的代码用 `$height` 和 `$width` 引用包装器 `height` 和 `width` 的被呈现值: ``` enum Size { From d4f1442dc95dbf132db387925b252e36c61a827d Mon Sep 17 00:00:00 2001 From: DanziChen Date: Mon, 11 Nov 2019 21:09:26 +0800 Subject: [PATCH 09/16] Update README.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 更新至 Swift 5.1 正式版 --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 363fe075..bbcd8995 100755 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ # 当前阶段 -- 更新到 Swift 5.1,2019-07-10 +- 更新到 Swift 5.1,2019-11-11 - 更新到 Swift 5.0,2019-04-05 - 更新到 Swift 4.2,2019-01-29 - 更新到 Swift 4.1,2018-04-12,感谢 [@Mylittleswift](https://github.com/Mylittleswift) @@ -142,4 +142,4 @@ diff 操作如下: # 协议 -和 [苹果官方文档](https://swift.org/documentation/) 协议一致:[Creative Commons Attribution 4.0 International (CC BY 4.0) License](https://creativecommons.org/licenses/by/4.0/)。 \ No newline at end of file +和 [苹果官方文档](https://swift.org/documentation/) 协议一致:[Creative Commons Attribution 4.0 International (CC BY 4.0) License](https://creativecommons.org/licenses/by/4.0/)。 From ec456eac27bd817e84429d5450da363bcde60cf0 Mon Sep 17 00:00:00 2001 From: DanziChen Date: Mon, 11 Nov 2019 21:13:11 +0800 Subject: [PATCH 10/16] Update README.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 更新至 Swift 5.1 --- source/README.md | 79 +++++++++++++++++++++++++----------------------- 1 file changed, 41 insertions(+), 38 deletions(-) diff --git a/source/README.md b/source/README.md index 3a857ea6..1c069896 100755 --- a/source/README.md +++ b/source/README.md @@ -1,21 +1,25 @@ # Swift 文档修订历史 -### 2019-06-03 +### 2019-09-10 * 更新至 Swift 5.1。 -* 在 [不透明类型](../02_language_guide/23_Opaque_Types.md) 篇章中新增了有关函数返回值遵循指定协议,而不需要提供指定返回类型的内容。 +* 在 [不透明类型](../02_language_guide/27_Opaque_Types.md) 篇章中新增了有关函数返回值遵循指定协议,而不需要提供指定返回类型的内容。 +* 在 [属性包装器](../02_language_guide/10_Properties.md#property-wrappers) 章节中新增了有关属性包装器的内容。 +* 在 [冻结](../03_language_reference/07_Attributes.md#frozen) 章节中新增了有关因库演变而需要的枚举和结构体冻结。 * 新增 [隐式返回的函数](../02_language_guide/06_Functions.md#functions-with-an-implicit-return) 和 [简化 Getter 声明](../02_language_guide/10_Properties.md#shorthand-getter-declaration) 章节,其中包含函数省略 `return` 的内容。 -* 在 [类型下标](../02_language_guide/12_Subscripts.md#type-subscripts) 章节中新增有关在类型中使用下标的内容。 +* 在 [类型下标](../02_language_guide/12_Subscripts.md#type-subscripts) 章节中新增了有关在类型中使用下标的内容。 +* 更新 [枚举 Case 模式匹配](../03_language_reference/08_Patterns.md#enumeration-case-pattern) 章节,现在枚举 case 模式匹配支持匹配可选值。 * 更新 [结构体的逐一成员构造器](../02_language_guide/14_Initialization.md#memberwise-initializers-for-structure-types) 章节,现在逐一成员构造器支持在属性有默认值时省略形参。 * 在 [动态查找成员](../03_language_reference/07_Attributes.md#dynamicmemberlookup) 章节中新增了有关在运行时用 key path 查找动态成员的内容。 +* 在 [条件编译代码块](../03_language_reference/05_Statements.md#Conditional-Compilation-Block) 中的目标环境里添加了 `macCatalyst`。 * 更新 [自身类型](../03_language_reference/03_Types.md#self-type-h) 章节,现在 `Self` 可以指向当前类,结构体或者枚举声明时的类型。 ### 2019-03-25 * 更新至 Swift 5。 -* 新增 [拓展字符串分隔符](../02_language_guide/03_Strings_And_Characters.md#extended-string-delimiters) 章节。更新 [字符串字面量](../03_language_reference/03_Lexical_Structure.md#string-literal) 章节,拓展有关字符串分隔符的内容。 +* 新增 [拓展字符串分隔符](../02_language_guide/03_Strings_And_Characters.md#extended-string-delimiters) 章节。更新 [字符串字面量](../03-language-reference/03-Lexical-Structure.md#string-literal) 章节,拓展有关字符串分隔符的内容。 * 新增 [动态调用](../03_language_reference/07_Attributes.md#dynamiccallable) 章节,其中包含使用 `dynamicCallable` 属性动态调用实例作为函数的内容。 -* 新增 [unknown](../03_language_reference/07_Attributes.md#unknown) 和 [未来枚举匹配](../03_language_reference/05_Statements.md#future-case2) 章节,其中包含了使用 `unknown` 来处理未来枚举可能发生改变的情形。 +* 新增 [unknown](../03_language_reference/07_Attributes.md#unknown) 和 [未来枚举匹配](../03-language-reference/05-Statements.md#future-case2) 章节,其中包含了使用 `unknown` 来处理未来枚举可能发生改变的情形。 * 在 [Key-Path 表达式](../03_language_reference/04_Expressions.md#key-path-expression) 章节新增了有关标示 key path (\\.self) 的内容。 * 在 [可选编译块](../03_language_reference/05_Statements.md#Conditional-Compilation-Block) 章节新增了有关小于比较符 `<` 的内容。 @@ -25,7 +29,7 @@ * 在 [遍历枚举情形](../02_language_guide/08_Enumerations.md#iterating-over-enumeration-cases) 章节新增了有关访问所有枚举情形的内容。 * 在 [编译诊断](../03_language_reference/05_Statements.md#compile-time-diagnostic-statement) 章节新增了有关 `#error` 和 `#warning` 的内容。 * 在 [属性声明](../03_language_reference/07_Attributes.md#Ideclaration-attributes) 章节中新增了有关 `inlinable` 和 `usableFromInline` 属性的内容。 -* 在 [属性声明](../03_language_reference/07_Attributes.md#Ideclaration-attributes) 章节中新增了有关 `requires_stored_property_inits` 和 `warn_unqualified_access` 属性的内容。 +* 在 [属性声明](../03_language_reference/07_Attributes.md#Ideclaration-attributes) 章节中新增了有关 `requires-stored-property-inits` 和 `warn-unqualified-access` 属性的内容。 * 在 [可选编译块](../03_language_reference/05_Statements.md#Conditional-Compilation-Block) 章节新增了有关如何根据 Swift 编译器版本对代码进行对应编译处理的内容。 * 在 [字面量语法](../03_language_reference/04_Expressions.md#literal-expression) 章节新增了有关 `#dsohandle` 的内容。 @@ -33,7 +37,7 @@ * 更新至 Swift 4.1。 * 在 [等价运算符](../02_language_guide/27_Advanced_Operators.md#equivalence-operators) 章节新增了有关等价运算符的合成实现的内容。 -* 在 [声明](../03_language_reference/06_Declarations.md) 篇章中 [申明拓展](../03_language_reference/06_Declarations.md#extension-declaration) 章节和 [协议](../02_language_guide/21_Protocols.md) 篇章中 [有条件地遵循协议](../02_language_guide/21_Protocols.md#Conditionally-Conforming-to-a-Protocol) 章节新增了有关协议有条件遵循的内容。 +* 在 [声明](../03_language_reference/06_Declarations.md) 篇章中 [申明拓展](../03_language_reference/06_Declarations.md#extension-declaration) 章节和 [协议](../02-language-guide/21-Protocols.md) 篇章中 [有条件地遵循协议](../02-language-guide/21-Protocols.md#Conditionally-Conforming-to-a-Protocol) 章节新增了有关协议有条件遵循的内容。 * 在 [关联类型约束中使用协议](../02_language_guide/22_Generics.md#using-a-protocol-in-its-associated-types-constraints) 章节中新增了有关递归协议约束的内容。 * 在 [条件编译块](../03_language_reference/05_Statements.md#Conditional-Compilation-Block) 章节中新增了有关 `canImport()` 和 `targetEnvironment()` 平台条件的内容。 @@ -47,10 +51,10 @@ * 更新至 Swift 4.0。 * 在 [内存安全](../02_language_guide/24_MemorySafety.md) 章节新增了有关内存互斥访问的内容。 * 新增 [带有泛型 Where 子句联类型](../02_language_guide/22_Generics.md#associated-types-with-a-generic-where-clause) 章节,现在可以使用泛型 `where` 子句约束关联类型。 -* 在 [字符串和字符](../02_language_guide/03_Strings_And_Characters.md) 篇章中 [字面量](../02_language_guide/03_Strings_And_Characters.md#string-literals) 章节以及 [词法结构](../03_language_reference/02_Lexical_Structure.md) 篇章的 [字符串字面量](../03_language_reference/02_Lexical_Structure.md#string-literal) 章节中新增了有关多行字符串字面量的内容。 +* 在 [字符串和字符](../02_language_guide/03_Strings_And_Characters.md) 篇章中 [字面量](../02_language_guide/03_Strings_And_Characters.md#string-literals) 章节以及 [词法结构](../03-language-reference/02-Lexical-Structure.md) 篇章的 [字符串字面量](../03-language-reference/02-Lexical-Structure.md#string-literal) 章节中新增了有关多行字符串字面量的内容。 * 更新 [声明属性](../03_language_reference/07_Attributes.md#Ideclaration-attributes) 中 `objc` 属性的讨论,现在该属性会在更少的位置被推断出来。 * 新增 [范型下标](../02_language_guide/22_Generics.md#generic-subscripts) 章节,现在下标也支持范型特性了。 -* 更新 [协议](../02_language_guide/21_Protocols.md) 篇章中 [协议组合](../02_language_guide/21_Protocols.md#protocol-composition) 章节和 [类型](../03_language_reference/03_Types.md) 篇章中 [协议组合类型](../03_language_reference/03_Types.md#protocol-composition-type-h) 章节的讨论,现在协议组合类型支持进行父类约束了。 +* 更新 [协议](../02_language_guide/21_Protocols.md) 篇章中 [协议组合](../02_language_guide/21_Protocols.md#protocol-composition) 章节和 [类型](../03-language-reference/03-Types.md) 篇章中 [协议组合类型](../03-language-reference/03-Types.md#protocol-composition-type-h) 章节的讨论,现在协议组合类型支持进行父类约束了。 * 更新 [拓展声明](../03_language_reference/06_Declarations.md#extension-declaration) 中有关协议扩展的讨论,现在它们不支持 `final` 特性了。 * 在 [断言和前置条件](../02_language_guide/01_TheBasics.md#assertions-and-preconditions) 章节中新增了部分前置条件和致命错误的内容。 @@ -81,20 +85,20 @@ * 更新 [高级操作符](../02_language_guide/27_Advanced_Operators.md) 篇章中有关操作符的讨论,现在你可以作为类型函数来实现,替代之前的全局函数实现方式。 * 在 [访问控制](../02_language_guide/26_Access_Control.md) 章节中新增有关对新的访问级别描述符 `open` 和 `fileprivate` 的内容。 * 更新 [函数声明](../03_language_reference/06_Declarations.md#function-declaration) 章节中有关 `inout` 的讨论,注意它现在出现在参数类型的前面,而不是在参数名称的前面。 -* 更新 [逃逸闭包](../02_language_guide/07_Closures.md#escaping-closures) 和 [自动闭包](../02_language_guide/07_Closures.md#autoclosures) 章节还有 [属性](../03_language_reference/07_Attributes.md) 篇章中有关 `@noescape` 和 `@autoclosure` 的讨论,现在他们是类型属性,而不是定义属性。 -* 在 [高级操作符](../02_language_guide/27_Advanced_Operators.md) 篇章中 [自定义中缀操作符的优先级](./02_language_guide/27_Advanced_Operators.md#precedence-and-associativity-for-custom-infix-operators) 章节和 [定义](../03_language_reference/06_Declarations.md) 篇章中 [优先级组声明](../03_language_reference/06_Declarations.md#precedence-group-declaration-modifiers) 章节中新增了有关操作符优先级组的内容。 +* 更新 [逃逸闭包](../02_language_guide/07_Closures.md#escaping-closures) 和 [自动闭包](../02-language-guide/07-Closures.md#autoclosures) 章节还有 [属性](../03-language-reference/07-Attributes.md) 篇章中有关 `@noescape` 和 `@autoclosure` 的讨论,现在他们是类型属性,而不是定义属性。 +* 在 [高级操作符](../02_language_guide/27_Advanced_Operators.md) 篇章中 [自定义中缀操作符的优先级](./02_language_guide/27_Advanced_Operators.md#precedence-and-associativity-for-custom-infix-operators) 章节和 [定义](../03-language-reference/06-Declarations.md) 篇章中 [优先级组声明](../03-language-reference/06-Declarations.md#precedence-group-declaration-modifiers) 章节中新增了有关操作符优先级组的内容。 * 更新一些讨论,使用 macOS 替换掉 OS X, Error 替换掉 ErrorProtocol。更新一些协议名称,比如使用 ExpressibleByStringLiteral 替换掉 StringLiteralConvertible。 -* 更新 [泛型](../02_language_guide/22_Generics.md) 篇章中 [泛型 Where 语句](../02_language_guide/22_Generics.md#extensions-with-a-generic-where-clause) 章节和 [泛型形参和实参](../03_language_reference/09_Generic_Parameters_And_Arguments.md) 篇章的讨论,现在泛型的 where 语句写在一个声明的最后。 +* 更新 [泛型](../02_language_guide/22_Generics.md) 篇章中 [泛型 Where 语句](../02_language_guide/22_Generics.md#extensions-with-a-generic-where-clause) 章节和 [泛型形参和实参](../03-language-reference/09-Generic-Parameters-And-Arguments.md) 篇章的讨论,现在泛型的 where 语句写在一个声明的最后。 * 更新 [逃逸闭包](../02_language_guide/07_Closures.md#escaping-closures) 章节中的讨论,现在闭包默认为非逃逸的。 -* 更新 [基础部分](../02_language_guide/01_TheBasics.md) 篇章中 [可选绑定](../02_language_guide/01_TheBasics.md#optional-binding) 章节和 [语句](../03_language_reference/05_Statements.md) 篇章中 [While 语句](../03_language_reference/05_Statements.md#while-statement) 章节中的讨论,现在 if,`while` 和 `guard` 语句使用逗号分隔条件列表,不需要使用 `where` 语句。 -* 在 [控制流](../02_language_guide/05_Control_Flow.md) 篇章中 [Switch](../02_language_guide/05_Control_Flow.md#switch) 章节和 [语句](../03_language_reference/05_Statements.md) 篇章中 [Switch 语句](../03_language_reference/05_Statements.md#switch-statement) 章节中新增了 switch cases 可以使用多模式的内容。 +* 更新 [基础部分](../02_language_guide/01_TheBasics.md) 篇章中 [可选绑定](../02_language_guide/01_TheBasics.md#optional-binding) 章节和 [语句](../03-language-reference/05-Statements.md) 篇章中 [While 语句](../03-language-reference/05-Statements.md#while-statement) 章节中的讨论,现在 if,`while` 和 `guard` 语句使用逗号分隔条件列表,不需要使用 `where` 语句。 +* 在 [控制流](../02_language_guide/05_Control_Flow.md) 篇章中 [Switch](../02_language_guide/05_Control_Flow.md#switch) 章节和 [语句](../03-language-reference/05-Statements.md) 篇章中 [Switch 语句](../03-language-reference/05-Statements.md#switch-statement) 章节中新增了 switch cases 可以使用多模式的内容。 * 更新 [函数类型](../03_language_reference/03_Types.md#function-type-h) 章节有关现在函数参数标签不包含在函数类型中的讨论。 -* 更新 [协议](../02_language_guide/21_Protocols.md) 篇章中 [协议组合](../02_language_guide/21_Protocols.md#protocol-composition) 章节和 [类型](../03_language_reference/03_Types.md) 篇章中 [协议组合类型](../03_language_reference/03_Types.md#protocol-composition-type-h) 章节中有关使用新的 Protocol1 & Protocol2 语法的内容。 +* 更新 [协议](../02_language_guide/21_Protocols.md) 篇章中 [协议组合](../02_language_guide/21_Protocols.md#protocol-composition) 章节和 [类型](../03-language-reference/03-Types.md) 篇章中 [协议组合类型](../03-language-reference/03-Types.md#protocol-composition-type-h) 章节中有关使用新的 Protocol1 & Protocol2 语法的内容。 * 更新动态类型表达式章节中使用新的 `type(of:)` 表达式的讨论。 * 更新 [行控制表达式](../03_language_reference/05_Statements.md#line-control-statement) 章节中使用 `#sourceLocation(file:line:)` 表达式的讨论。 * 更新 [永不返回函数](../03_language_reference/06_Declarations.md#functions-that-never-return) 章节中使用 新的 `Never` 类型的讨论。 * 在 [字面量表达式](../03_language_reference/04_Expressions.md#literal-expression) 章节中新增了有关 `playground` 字面量的内容。 -* 更新 [In-Out 参数](../03_language_reference/06_Declarations.md#in-out_parameters) 章节,标明只有非逃逸闭包能捕获 `in-out` 参数。 +* 更新 [In-Out 参数](../03_language_reference/06_Declarations.md#in-out-parameters) 章节,标明只有非逃逸闭包能捕获 `in-out` 参数。 * 更新 [默认参数值](../02_language_guide/06_Functions.md#default-parameter-values) 章节,现在默认参数不能在调用时候重新排序。 * 更新 [属性](../03_language_reference/07_Attributes.md) 篇章中有关属性参数使用分号的说明。 * 在 [重新抛出函数和方法](../03_language_reference/06_Declarations.md#rethrowing-functions-and-methods) 章节中新增了有关在 catch 代码块中抛出错误的重新抛出函数的内容。 @@ -114,7 +118,7 @@ * 在 [编译配置语句](../03_language_reference/05_Statements.md#Conditional-Compilation-Block) 章节新增了中有关如何根据 Swift 版本进行条件编译。 * 在 [显示成员表达式](../03_language_reference/04_Expressions.md#explicit-member-expression) 章节中新增了有关如何区分只有参数名不同的方法和构造器的内容。 * 在 [选择器表达式](../03_language_reference/04_Expressions.md#selector-expression7) 章节中新增了了针对 Objective-C 选择器的 `#selector` 语法。 -* 更新 [关联类型](../02_language_guide/22_Generics.md#associated-types) 和 [协议关联类型声明](../03_language_reference/06_Declarations.md#protocol_associated_type_declaration) 章节中有关使用 `associatedtype` 关键词修饰关联类型的讨论。 +* 更新 [关联类型](../02_language_guide/22_Generics.md#associated-types) 和 [协议关联类型声明](../03-language-reference/06-Declarations.md#protocol-associated-type-declaration) 章节中有关使用 `associatedtype` 关键词修饰关联类型的讨论。 * 更新 [可失败构造器](../02_language_guide/14_Initialization.md#failable-initializers) 章节中有关当构造器在实例完全初始化之前返回 `nil` 的相关内容。 * 在 [比较运算符](../02_language_guide/BasicOperators.md#comparison-operators) 章节中新增了比较元组的内容。 * 在 [关键字和标点符号](../03_language_reference/02_Lexical_Structure.md#keywords-and-punctuation) 章节中新增了使用关键字作为外部参数名的内容。 @@ -130,10 +134,10 @@ ### 2015-10-20 * 更新至 Swift 2.1。 -* 更新 [字符串插值](../02_language_guide/03_Strings_And_Characters.md#string-interpolation) 和 [字符串字面量](../03_language_reference/02_Lexical_Structure.md#string-literal) 章节,现在字符串插值可包含字符串字面量。 +* 更新 [字符串插值](../02_language_guide/03_Strings_And_Characters.md#string-interpolation) 和 [字符串字面量](../03-language-reference/02-Lexical-Structure.md#string-literal) 章节,现在字符串插值可包含字符串字面量。 * 在 [逃逸闭包](../02_language_guide/07_Closures.md#escaping-closures) 章节中新增了有关 `@noescape` 属性的相关内容。 -* 更新 [声明特性](../03_language_reference/07_Attributes.md#Ideclaration-attributes) 和 [编译配置语句](../03_language_reference/05_Statements.md#Conditional-Compilation-Block) 章节中与 tvOS 相关的内容。 -* 在 [In-Out 参数](../03_language_reference/06_Declarations.md#in-out_parameters) 章节中新增了与 in-out 参数行为相关的内容。 +* 更新 [声明特性](../03_language_reference/07_Attributes.md#Ideclaration-attributes) 和 [编译配置语句](../03-language-reference/05-Statements.md#Conditional-Compilation-Block) 章节中与 tvOS 相关的内容。 +* 在 [In-Out 参数](../03_language_reference/06_Declarations.md#in-out-parameters) 章节中新增了与 in-out 参数行为相关的内容。 * 在 [捕获列表](../03_language_reference/04_Expressions.md#capture-lists) 章节新增了有关指定闭包捕获列表被捕获时捕获值的相关内容。 * 更新 [可选链式调用访问属性](../02_language_guide/16_Optional_Chaining.md#accessing-properties-through-optional-chaining) 章节,阐明了如何通过可选链式调用进行赋值。 * 改进 [自动闭包](../02_language_guide/07_Closures.md#autoclosures) 章节中对自闭包的讨论。 @@ -142,21 +146,21 @@ ### 2015-09-16 * 更新至 Swift 2.0。 -* 在 [错误处理](../02_language_guide/17_Error_Handling.md) 篇章中新增了有关错误处理的相关内容,包括 [Do 语句](../03_language_reference/05_Statements.md#do-statement)、 [Throw 语句](../03_language_reference/05_Statements.md#throw-statement)、 [Defer 语句](../03_language_reference/05_Statements.md##defer-statements) 以及 [try 运算符](../03_language_reference/04_Expressions.md#try-operator)。 +* 在 [错误处理](../02_language_guide/17_Error_Handling.md) 篇章中新增了有关错误处理的相关内容,包括 [Do 语句](../03_language_reference/05_Statements.md#do-statement)、 [Throw 语句](../03-language-reference/05-Statements.md#throw-statement)、 [Defer 语句](../03-language-reference/05-Statements.md##defer-statements) 以及 [try 运算符](../03-language-reference/04-Expressions.md#try-operator)。 * 更新 [错误表示和抛出](../02_language_guide/17_Error_Handling.md#representing-and-throwing-errors) 章节,现在所有类型都可以遵循 `ErrorType` 协议了。 -* 在 [将错误装换成可选值](../02_language_guide/17_Error_Handling.md#converting_errors_to_optional_values) 篇章增加了 `try?` 关键字相关内容。 -* 在 [枚举](../02_language_guide/08_Enumerations.md) 篇章的 [递归枚举](../02_language_guide/08_Enumerations.md#recursive-enumerations) 章节以及以及 [声明](../03_language_reference/06_Declarations.md) 篇章的 [任意类型用例的枚举](../03_language_reference/06_Declarations.md#enumerations-with-cases-of-any-type) 章节中新增了递归枚举相关内容。 -* 在 [控制流](../02_language_guide/05_Control_Flow.md) 篇章的 [API 可用性检查](../02_language_guide/05_Control_Flow.md#checking-api-availability) 章节和 [语句](../03_language_reference/05_Statements.md) 篇章的 [可用性条件](../03_language_reference/05_Statements.md#availability-condition) 章节中新增了有关 API 可用性检查相关的内容。 -* 在 [控制流](../02_language_guide/05_Control_Flow.md) 篇章的 [尽早退出](../02_language_guide/05_Control_Flow.md#early-exit) 章节和 [语句](../03_language_reference/05_Statements.md) 篇章的 [Guard 语句](../03_language_reference/05_Statements.md#guard-statement) 章节新增了与 `guard` 语句相关的内容。 +* 在 [将错误装换成可选值](../02_language_guide/17_Error_Handling.md#converting-errors-to-optional-values) 篇章增加了 `try?` 关键字相关内容。 +* 在 [枚举](../02_language_guide/08_Enumerations.md) 篇章的 [递归枚举](../02_language_guide/08_Enumerations.md#recursive-enumerations) 章节以及以及 [声明](../03-language-reference/06-Declarations.md) 篇章的 [任意类型用例的枚举](../03-language-reference/06-Declarations.md#enumerations-with-cases-of-any-type) 章节中新增了递归枚举相关内容。 +* 在 [控制流](../02_language_guide/05_Control_Flow.md) 篇章的 [API 可用性检查](../02_language_guide/05_Control_Flow.md#checking-api-availability) 章节和 [语句](../03-language-reference/05-Statements.md) 篇章的 [可用性条件](../03-language-reference/05-Statements.md#availability-condition) 章节中新增了有关 API 可用性检查相关的内容。 +* 在 [控制流](../02_language_guide/05_Control_Flow.md) 篇章的 [尽早退出](../02_language_guide/05_Control_Flow.md#early-exit) 章节和 [语句](../03-language-reference/05-Statements.md) 篇章的 [Guard 语句](../03-language-reference/05-Statements.md#guard-statement) 章节新增了与 `guard` 语句相关的内容。 * 在 [协议](../02_language_guide/21_Protocols.md) 篇章中 [协议扩展](../02_language_guide/21_Protocols.md#protocol-extensions) 章节中新增了有关协议扩展的内容。 * 在 [访问控制](../02_language_guide/26_Access_Control.md) 篇章的 [单元测试 target 的访问级别](../02_language_guide/26_Access_Control.md#access-levels-for-unit-test-targets) 章节中新增了有关单元测试访问控制相关的内容。 * 在 [模式](../03_language_reference/08_Patterns.md) 篇章的 [可选模式](../03_language_reference/08_Patterns.md#optional-pattern) 章节中新增了可选模式相关内容。 * 更新 [Repeat-While](../02_language_guide/05_Control_Flow.md#repeat-while) 章节中有关 `repeat-while` 循环相关的内容。 * 更新 [字符串和字符](../02_language_guide/03_Strings_And_Characters.md) 章节,现在 `String` 类型在 Swift 标准库中不再遵循 `CollectionType` 协议。 -* 在 [常量与变量打印](../02_language_guide/01_TheBasics.md#printing) 章节中新增了新 Swift 标准库中有关 `print(_:separator:terminator) ` 相关内容。 -* 在 [枚举](../02_language_guide/08_Enumerations.md) 篇章的 [原始值的隐式赋值](../02_language_guide/08_Enumerations.md#implicitly-assigned-raw-values) 章节和 [声明](../03_language_reference/06_Declarations.md) 篇章的 [包含原始值类型的枚举](../03_language_reference/06_Declarations.md#enumerations-with-cases-of-a-raw-value-type) 章节中新增了有关包含 `String` 原始值的枚举用例的行为相关内容。 +* 在 [常量与变量打印](../02_language_guide/01_TheBasics.md#printing) 章节中新增了新 Swift 标准库中有关 `print(-:separator:terminator) ` 相关内容。 +* 在 [枚举](../02_language_guide/08_Enumerations.md) 篇章的 [原始值的隐式赋值](../02_language_guide/08_Enumerations.md#implicitly-assigned-raw-values) 章节和 [声明](../03-language-reference/06-Declarations.md) 篇章的 [包含原始值类型的枚举](../03-language-reference/06-Declarations.md#enumerations-with-cases-of-a-raw-value-type) 章节中新增了有关包含 `String` 原始值的枚举用例的行为相关内容。 * 在 [自动闭包](../02_language_guide/07_Closures.md#autoclosures) 章节中新增了有关 `@autoclosure` 特性的相关内容,包括它的 `@autoclosure(escaping)` 形式。 -* 更新 [声明特性](../03_language_reference/07_Attributes.md#Ideclaration-attributes) 章节中有关 `@avaliable` 和 `warn_unused_result` 特性的相关内容。 +* 更新 [声明特性](../03_language_reference/07_Attributes.md#Ideclaration-attributes) 章节中有关 `@avaliable` 和 `warn-unused-result` 特性的相关内容。 * 更新 [类型特性](../03_language_reference/07_Attributes.md#type-attributes) 章节中有关 `@convention` 特性的相关内容。 * 在 [可选绑定](../02_language_guide/01_TheBasics.md#optional-binding) 章节中新增了有关使用 `where` 子句进行多可选绑定的相关内容。 * 在 [字符串字面量](../03_language_reference/02_Lexical_Structure.md#string-literal) 章节中新增了有关在编译时使用 `+` 运算符拼接字符串字面量的相关内容。 @@ -171,11 +175,11 @@ * 在 [元类型](../03_language_reference/03_Types.md#metatype-type-h) 章节新增了一处说明,有关如何从元类型值中构造类实例相关内容。 * 在 [弱引用](../02_language_guide/24_Automatic_Reference_Counting.md#weak-references) 章节新增了一处说明,有关弱引用作为缓存所存在的不足。 * 更新 [类型特性](../02_language_guide/10_Properties.md#type-properties) 章节,提到了存储型特性其实是懒加载。 -* 更新 [捕获类型](../02_language_guide/07_Closures.md#capturing_values) 章节,阐明了变量和常量在闭包中如何被捕获。 +* 更新 [捕获类型](../02_language_guide/07_Closures.md#capturing-values) 章节,阐明了变量和常量在闭包中如何被捕获。 * 更新 [声明特性](../03_language_reference/07_Attributes.md#Ideclaration-attributes) 章节,用以描述何时在类中使用 `@objc` 关键字。 -* 在 [错误处理](../02_language_guide/17_Error_Handling.md#handling-errors) 章节中新增了一处说明,有关执行 `throw` 语句的性能。在 [Do 语句](../03_language_reference/05_Statements.md#do-statement) 章节的 do 语句部分也新增了类似内容。 +* 在 [错误处理](../02_language_guide/17_Error_Handling.md#handling-errors) 章节中新增了一处说明,有关执行 `throw` 语句的性能。在 [Do 语句](../03-language-reference/05-Statements.md#do-statement) 章节的 do 语句部分也新增了类似内容。 * 更新 [类型特性](../02_language_guide/10_Properties.md#type-properties) 章节中有关类、结构体和枚举的存储型和计算型特性相关的内容。 -* 更新 [Break 语句](../03_language_reference/05_Statements.md#break_statement) 章节中有关带标签的 break 语句相关内容。 +* 更新 [Break 语句](../03_language_reference/05_Statements.md#break-statement) 章节中有关带标签的 break 语句相关内容。 * 在 [属性观察器](../02_language_guide/10_Properties.md#property-observers) 章节更新了一处说明,用来明确 `willSet` 和 `didSet` 观察器的行为。 * 在 [访问级别](../02_language_guide/26_Access_Control.md#access-levels) 章节新增了有关 `private` 作用域的相关内容说明。 * 在 [弱引用](../02_language_guide/24_Automatic_Reference_Counting.md#weak-references) 章节新增了有关弱应用在垃圾回收系统和 ARC 之间的区别的说明。 @@ -212,9 +216,9 @@ * 新增 [失败构造器](../02_language_guide/14_Initialization.md#failable-initializers) 的完整指引。 * 在协议中新增了 [失败构造器要求](../02_language_guide/21_Protocols.md#failable-initializer-requirements) 的描述。 * 常量和变量的 `Any` 类型现可以包含函数实例。更新了有关 `Any` 相关的示例来展示如何在 `switch` 语句中如何检查并转换到一个函数类型。 -* 带有原始值的枚举类型增加了一个 `rawValue` 属性替代 `toRaw()` 方法,同时使用了一个以 `rawValue` 为参数的失败构造器来替代 `fromRaw()` 方法。更多的内容,请看 [原始值](../02_language_guide/08_Enumerations.md#raw-values) 和 [带原始值的枚举类型](../03_language_reference/06_Declarations.md#enumerations-with-cases-of-a-raw-value-type)。 +* 带有原始值的枚举类型增加了一个 `rawValue` 属性替代 `toRaw()` 方法,同时使用了一个以 `rawValue` 为参数的失败构造器来替代 `fromRaw()` 方法。更多的内容,请看 [原始值](../02_language_guide/08_Enumerations.md#raw-values) 和 [带原始值的枚举类型](../03-language-reference/06-Declarations.md#enumerations-with-cases-of-a-raw-value-type)。 * 新增 [Failable Initializer](../03_language_reference/06_Declarations.md#failable-initializers) 的参考章节,它可以触发初始化失败。 -* 自定义运算符现在可以包含 `?` 字符,更新了 [运算符](../03_language_reference/02_Lexical_Structure.md#operator) 涉及改进后的规则的部分,并且在 [自定义运算符](../02_language_guide/27_Advanced_Operators.md#custom-operators) 章节中删除了重复的运算符有效字符集合。 +* 自定义运算符现在可以包含 `?` 字符,更新了 [运算符](../03_language_reference/02_Lexical_Structure.md#operator) 涉及改进后的规则的部分,并且在 [自定义运算符](../02-language-guide/27-Advanced-Operators.md#custom-operators) 章节中删除了重复的运算符有效字符集合。 ### 2014-08-18 @@ -227,11 +231,11 @@ * [可选类型](../02_language_guide/01_TheBasics.md#optionals) 若有值时,不再隐式的转换为 `true`,同样,若无值时,也不再隐式的转换为 `false`,这是为了避免在判别 optional `Bool` 的值时产生困惑。 替代的方案是,用`==` 或 `!=` 运算符显式地去判断 Optinal 是否是 `nil`,以确认其是否包含值。 * Swift 新增了一个 [Nil 合并运算符](../02_language_guide/BasicOperators.md#nil-coalescing-operator) (`a ?? b`) , 该表达式中,如果 Optional `a` 的值存在,则取得它并返回,若 Optional `a` 为 `nil`,则返回默认值 `b` * 更新和扩展 [字符串的比较](../02_language_guide/03_Strings_And_Characters.md#comparing-strings) ,用以反映和展示'字符串和字符的比较',以及'前缀(prefix)/后缀(postfix)比较'都开始基于扩展字符集(extended grapheme clusters)规范的等价比较。 -* 现在,你可以通过下标赋值或者 [可选调用链](../02_language_guide/16_Optional_Chaining.md) 中的可变方法和操作符来给属性设值。相应地更新了有关 [通过可选链接访问属性](../02_language_guide/16_Optional_Chaining.md#accessing-properties-through-optional-chaining) 的内容,并扩展了 [通过可选链接调用方法](../02_language_guide/16_Optional_Chaining.md#calling-methods-through-optional-chaining) 时检查方法调用成功的示例,以显示如何检查属性设置是否成功。 +* 现在,你可以通过下标赋值或者 [可选调用链](../02_language_guide/16_Optional_Chaining.md) 中的可变方法和操作符来给属性设值。相应地更新了有关 [通过可选链接访问属性](../02_language_guide/16_Optional_Chaining.md#accessing-properties-through-optional-chaining) 的内容,并扩展了 [通过可选链接调用方法](../02-language-guide/16-Optional-Chaining.md#calling-methods-through-optional-chaining) 时检查方法调用成功的示例,以显示如何检查属性设置是否成功。 * 在可选链中新增了 [访问可选类型的下标脚注](../02_language_guide/16_Optional_Chaining.md#accessing-subscripts-through-optional-chaining) 章节。 * 更新 [访问和修改数组](../02_language_guide/CollectionTypes.md#accessing-and-modifying-a-dictionary) 章节以标示,从该版本起,不能再通过 `+=` 运算符给一个数组新增一个新的项。对应的替代方案是,使 `append` 方法,或者通过 `+=` 运算符来新增一个只有一个项的数组。 * 新增一处说明,在 [范围运算符](../02_language_guide/BasicOperators.md#range-operators) 中,比如, `a..b` 和 `a.. Date: Mon, 11 Nov 2019 21:23:55 +0800 Subject: [PATCH 11/16] Update contributors.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 更新贡献者 --- source/contributors.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/contributors.md b/source/contributors.md index be5ec47d..ff95792b 100755 --- a/source/contributors.md +++ b/source/contributors.md @@ -14,10 +14,12 @@ Swift 官方文档中文翻译由 [numbbbbb](https://github.com/numbbbbb) 发起 - [Hale](https://github.com/wuqiuhao) - [Joeytat](https://github.com/joeytat) - [jojotov](https://github.com/jojotov) +- [Licardo](https://github.com/L1cardo) - [Khala-wan](https://github.com/Khala-wan) - [Nemocdz](https://github.com/Nemocdz) - [numbbbbb](https://github.com/numbbbbb) - [pmst](https://github.com/colourful987) +- [Phenmod](https://github.com/Phenmod) - [RickeyBoy](https://github.com/RickeyBoy) - [SunsetWan](https://github.com/SunsetWan) - [WAMaker](https://github.com/WAMaker) From 55001fd340e3ad4bd2b6c5f9d5562c3b0e9d1410 Mon Sep 17 00:00:00 2001 From: DanziChen Date: Mon, 11 Nov 2019 21:36:27 +0800 Subject: [PATCH 12/16] Update 10_Properties.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 增加代码块高亮 --- source/02_language_guide/10_Properties.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/source/02_language_guide/10_Properties.md b/source/02_language_guide/10_Properties.md index 8606107f..2a749c7a 100755 --- a/source/02_language_guide/10_Properties.md +++ b/source/02_language_guide/10_Properties.md @@ -286,7 +286,7 @@ stepCounter.totalSteps = 896 定义一个属性包装器,你需要创建一个定义 `wrappedValue` 属性的结构体、枚举或者类。在下面的代码中,`TwelveOrLess` 结构体确保它包装的值始终是小于等于 12 的数字。如果要求它存储一个更大的数字,它则会存储 12 这个数字。 -``` +```swift @propertyWrapper struct TwelveOrLess { private var number = 0 @@ -304,7 +304,7 @@ struct TwelveOrLess { 通过在属性之前写上包装器名称作为特性的方式,你可以把一个包装器应用到一个属性上去。这里有个存储小矩形的结构体。通过 `TwelveOrLess` 属性包装器实现类似(挺随意的)对“小”的定义。 -``` +```swift struct SmallRectangle { @TwelveOrLess var height: Int @TwelveOrLess var width: Int @@ -327,7 +327,7 @@ print(rectangle.height) 当你把一个包装器应用到一个属性上时,编译器将合成提供包装器存储空间和通过包装器访问属性的代码。(属性包装器只负责存储被包装值,所以没有合成这些代码。)不利用这个特性语法的情况下,你可以写出使用属性包装器行为的代码。举例来说,这是先前代码清单中的 `SmallRectangle` 的另一个版本。这个版本将其属性明确地包装在 `TwelveOrLess` 结构体中,而不是把 `@TwelveOrLess` 作为特性写下来: -``` +```swift struct SmallRectangle { private var _height = TwelveOrLess() private var _width = TwelveOrLess() @@ -348,7 +348,7 @@ struct SmallRectangle { 上面例子中的代码通过在 `TwelveOrLess` 的定义中赋予 `number` 一个初始值来设置被包装属性的初始值。使用这个属性包装器的代码没法为被 `TwelveOrLess` 包装的属性指定其他初始值。举例来说,`SmallRectangle` 的定义没法给 `height` 或者 `width` 一个初始值。为了支持设定一个初始值或者其他自定义操作,属性包装器需要添加一个构造器。这是 `TwelveOrLess` 的扩展版本,称为 `SmallNumber`。`SmallNumber` 定义了能设置被包装值和最大值的构造器: -``` +```swift @propertyWrapper struct SmallNumber { private var maximum: Int @@ -378,7 +378,7 @@ struct SmallNumber { 当你把包装器应用于属性且没有设定初始值时,Swift 使用 `init()` 构造器来设置包装器。举个例子: -``` +```swift struct ZeroRectangle { @SmallNumber var height: Int @SmallNumber var width: Int @@ -393,7 +393,7 @@ print(zeroRectangle.height, zeroRectangle.width) 当你为属性指定初始值时,Swift 使用 `init(wrappedValue:)` 构造器来设置包装器。举个例子: -``` +```swift struct UnitRectangle { @SmallNumber var height: Int = 1 @SmallNumber var width: Int = 1 @@ -408,7 +408,7 @@ print(unitRectangle.height, unitRectangle.width) 当你在自定义特性后面把实参写在括号里时,Swift 使用接受这些实参的构造器来设置包装器。举例来说,如果你提供初始值和最大值,Swift 使用 `init(wrappedValue:maximum:)` 构造器: -``` +```swift struct NarrowRectangle { @SmallNumber(wrappedValue: 2, maximum: 5) var height: Int @SmallNumber(wrappedValue: 3, maximum: 4) var width: Int @@ -430,7 +430,7 @@ print(narrowRectangle.height, narrowRectangle.width) 当包含属性包装器实参时,你也可以使用赋值来指定初始值。Swift 将赋值视为 `wrappedValue` 参数,且使用接受被包含的实参的构造器。举个例子: -``` +```swift struct MixedRectangle { @SmallNumber var height: Int = 1 @SmallNumber(maximum: 9) var width: Int = 2 @@ -453,7 +453,7 @@ print(mixedRectangle.height) 在之前 `SmallNumber` 的例子中,如果你尝试把这个属性设置为一个很大的数值,属性包装器会在存储这个数值之前调整这个数值。以下的代码把被呈现值添加到 `SmallNumber` 结构体中来追踪在存储新值之前属性包装器是否为这个属性调整了新值。 -``` +```swift @propertyWrapper struct SmallNumber { private var number = 0 @@ -491,7 +491,7 @@ print(someStructure.$someNumber) 当从类型的一部分代码中访问被呈现值,例如属性 getter 或实例方法,你可以在属性名称之前省略 `self.`,就像访问其他属性一样。以下示例中的代码用 `$height` 和 `$width` 引用包装器 `height` 和 `width` 的被呈现值: -``` +```swift enum Size { case small, large } @@ -663,4 +663,4 @@ print(rightChannel.currentLevel) // 输出“10” print(AudioChannel.maxInputLevelForAllChannels) // 输出“10” -``` \ No newline at end of file +``` From 670cef47eddb689ac90405909b12cf86f1b84224 Mon Sep 17 00:00:00 2001 From: everettjf Date: Tue, 19 Nov 2019 09:58:08 +0800 Subject: [PATCH 13/16] typo fix (#1018) --- source/01_welcome_to_swift/03_a_swift_tour.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/01_welcome_to_swift/03_a_swift_tour.md b/source/01_welcome_to_swift/03_a_swift_tour.md index d87b8388..b58eab60 100755 --- a/source/01_welcome_to_swift/03_a_swift_tour.md +++ b/source/01_welcome_to_swift/03_a_swift_tour.md @@ -18,7 +18,7 @@ print("Hello, world!") ## 简单值 {#simple-values} -使用 `let` 来声明常量,使用 `var` 来声明变量。一个常量的值,在编译的时候,并不需要有明确的值,但是你只能为它赋值一次。这说明你可以用一个常量来命名一个值,一次赋值就即可在多个地方使用。 +使用 `let` 来声明常量,使用 `var` 来声明变量。一个常量的值,在编译的时候,并不需要有明确的值,但是你只能为它赋值一次。这说明你可以用一个常量来命名一个值,一次赋值就可在多个地方使用。 ```swift var myVariable = 42 From 89aa08ab5793e9a0aaef5e679160440d15b78ca1 Mon Sep 17 00:00:00 2001 From: Elf Sundae Date: Mon, 27 Jan 2020 13:16:35 +0800 Subject: [PATCH 14/16] Fix anchor link --- source/02_language_guide/02_Basic_Operators.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/02_language_guide/02_Basic_Operators.md b/source/02_language_guide/02_Basic_Operators.md index 9c5bbc0a..1e0a586b 100755 --- a/source/02_language_guide/02_Basic_Operators.md +++ b/source/02_language_guide/02_Basic_Operators.md @@ -402,7 +402,7 @@ if !allowedEntry { 在示例代码中,小心地选择布尔常量或变量有助于代码的可读性,并且避免使用双重逻辑非运算,或混乱的逻辑语句。 -### 逻辑与运算符 #{logical-and-operator} +### 逻辑与运算符 {#logical-and-operator} *逻辑与运算符*(`a && b`)表达了只有 `a` 和 `b` 的值都为 `true` 时,整个表达式的值才会是 `true`。 @@ -421,7 +421,7 @@ if enteredDoorCode && passedRetinaScan { // 输出“ACCESS DENIED” ``` -### 逻辑或运算符 #{logical-or-operator} +### 逻辑或运算符 {#logical-or-operator} 逻辑或运算符(`a || b`)是一个由两个连续的 `|` 组成的中置运算符。它表示了两个逻辑表达式的其中一个为 `true`,整个表达式就为 `true`。 From f416e311eb87d192464682e1d54d5a13f2f9ff79 Mon Sep 17 00:00:00 2001 From: Elf Sundae Date: Thu, 30 Jan 2020 00:16:12 +0800 Subject: [PATCH 15/16] Update 03_Strings_and_Characters.md (#1022) * Update 03_Strings_and_Characters.md * SubString -> Substring * Fix StringProtocol documentation URL --- .../02_language_guide/03_Strings_and_Characters.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/source/02_language_guide/03_Strings_and_Characters.md b/source/02_language_guide/03_Strings_and_Characters.md index 383766e2..b85a5123 100755 --- a/source/02_language_guide/03_Strings_and_Characters.md +++ b/source/02_language_guide/03_Strings_and_Characters.md @@ -1,6 +1,6 @@ # 字符串和字符 -*字符串*是是一系列字符的集合,例如 `"hello, world"`,`"albatross"`。Swift 的字符串通过 `String` 类型来表示。而 `String` 内容的访问方式有多种,例如以 `Character` 值的集合。 +*字符串*是一系列字符的集合,例如 `"hello, world"`,`"albatross"`。Swift 的字符串通过 `String` 类型来表示。而 `String` 内容的访问方式有多种,例如以 `Character` 值的集合。 Swift 的 `String` 和 `Character` 类型提供了一种快速且兼容 Unicode 的方式来处理代码中的文本内容。创建和操作字符串的语法与 C 语言中字符串操作相似,轻量并且易读。通过 `+` 符号就可以非常简单的实现两个字符串的拼接操作。与 Swift 中其他值一样,能否更改字符串的值,取决于其被定义为常量还是变量。你可以在已有字符串中插入常量、变量、字面量和表达式从而形成更长的字符串,这一过程也被称为字符串插值。尤其是在为显示、存储和打印创建自定义字符串值时,字符串插值操作尤其有用。 @@ -384,7 +384,7 @@ greeting[index] ```swift greeting[greeting.endIndex] // error -greeting.index(after: endIndex) // error +greeting.index(after: greeting.endIndex) // error ``` 使用 `indices` 属性会创建一个包含全部索引的范围(`Range`),用来在一个字符串中访问单个字符。 @@ -430,7 +430,7 @@ welcome.removeSubrange(range) ## 子字符串 {#substrings} -当你从字符串中获取一个子字符串 —— 例如,使用下标或者 `prefix(_:)` 之类的方法 —— 就可以得到一个 `SubString` 的实例,而非另外一个 `String`。Swift 里的 `SubString` 绝大部分函数都跟 `String` 一样,意味着你可以使用同样的方式去操作 `SubString` 和 `String`。然而,跟 `String` 不同的是,你只有在短时间内需要操作字符串时,才会使用 `SubString`。当你需要长时间保存结果时,就把 `SubString` 转化为 `String` 的实例: +当你从字符串中获取一个子字符串 —— 例如,使用下标或者 `prefix(_:)` 之类的方法 —— 就可以得到一个 `Substring` 的实例,而非另外一个 `String`。Swift 里的 `Substring` 绝大部分函数都跟 `String` 一样,意味着你可以使用同样的方式去操作 `Substring` 和 `String`。然而,跟 `String` 不同的是,你只有在短时间内需要操作字符串时,才会使用 `Substring`。当你需要长时间保存结果时,就把 `Substring` 转化为 `String` 的实例: ```swift let greeting = "Hello, world!" @@ -442,15 +442,15 @@ let beginning = greeting[.. 注意 > -> `String` 和 `SubString` 都遵循 `StringProtocol` 协议,这意味着操作字符串的函数使用 `StringProtocol` 会更加方便。你可以传入 `String` 或 `SubString` 去调用函数。 +> `String` 和 `Substring` 都遵循 [`StringProtocol`](https://developer.apple.com/documentation/swift/stringprotocol) 协议,这意味着操作字符串的函数使用 `StringProtocol` 会更加方便。你可以传入 `String` 或 `Substring` 去调用函数。 ## 比较字符串 {#comparing-strings} From 7d2b9492361f3188b5e305348e7383e2e3f4c7ce Mon Sep 17 00:00:00 2001 From: Jie Liang Date: Thu, 6 Feb 2020 11:52:12 -0600 Subject: [PATCH 16/16] Update 02_Basic_Operators.md --- source/02_language_guide/02_Basic_Operators.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/02_language_guide/02_Basic_Operators.md b/source/02_language_guide/02_Basic_Operators.md index 1e0a586b..01ba613b 100755 --- a/source/02_language_guide/02_Basic_Operators.md +++ b/source/02_language_guide/02_Basic_Operators.md @@ -286,7 +286,7 @@ var colorNameToUse = userDefinedColorName ?? defaultColorName `userDefinedColorName` 变量被定义为一个可选的 `String` 类型,默认值为 `nil`。由于 `userDefinedColorName` 是一个可选类型,我们可以使用空合运算符去判断其值。在上一个例子中,通过空合运算符为一个名为 `colorNameToUse` 的变量赋予一个字符串类型初始值。 由于 `userDefinedColorName` 值为空,因此表达式 `userDefinedColorName ?? defaultColorName` 返回 `defaultColorName` 的值,即 `red`。 -如果你分配一个非空值(`non-nil`)给 `userDefinedColorName`,再次执行空合运算,运算结果为封包在 `userDefaultColorName` 中的值,而非默认值。 +如果你分配一个非空值(`non-nil`)给 `userDefinedColorName`,再次执行空合运算,运算结果为封包在 `userDefinedColorName` 中的值,而非默认值。 ```swift userDefinedColorName = "green"