@@ -128,28 +128,28 @@ default:
对于库存跟踪系统来说,能够把 UPC-A 码作为三个整型值的元组,和把 QR 码作为一个任何长度的字符串存储起来是方便的。
-在 Swift 中,用来定义两种商品条码的枚举是这样子的:
+在 Swift 中,使用如下方式定义两种商品条码的枚举:
```swift
enum Barcode {
- case UPCA(Int, Int, Int)
+ case UPCA(Int, Int, Int, Int)
case QRCode(String)
}
```
以上代码可以这么理解:
-“定义一个名为`Barcode`的枚举类型,它可以是`UPCA`的一个相关值(`Int`,`Int`,`Int`),或者`QRCode`的一个字符串类型(`String`)相关值。”
+“定义一个名为`Barcode`的枚举类型,它可以是`UPCA`的一个相关值(`Int`,`Int`,`Int`,`Int`),或者是`QRCode`的一个字符串类型(`String`)相关值。”
这个定义不提供任何`Int`或`String`的实际值,它只是定义了,当`Barcode`常量和变量等于`Barcode.UPCA`或`Barcode.QRCode`时,相关值的类型。
然后可以使用任何一种条码类型创建新的条码,如:
```swift
-var productBarcode = Barcode.UPCA(8, 85909_51226, 3)
+var productBarcode = Barcode.UPCA(8, 85909, 51226, 3)
```
-以上例子创建了一个名为`productBarcode`的新变量,并且赋给它一个`Barcode.UPCA`的相关元组值`(8, 8590951226, 3)`。提供的“标识符”值在整数字中有一个下划线,使其便于阅读条形码。
+以上例子创建了一个名为`productBarcode`的变量,并且赋给它一个`Barcode.UPCA`的相关元组值`(8, 85909, 51226, 3)`。
同一个商品可以被分配给一个不同类型的条形码,如:
@@ -163,24 +163,24 @@ productBarcode = .QRCode("ABCDEFGHIJKLMNOP")
```swift
switch productBarcode {
-case .UPCA(let numberSystem, let identifier, let check):
- print("UPC-A with value of \(numberSystem), \(identifier), \(check).")
+case .UPCA(let numberSystem, let manufacturer, let product, let check):
+ print("UPC-A: \(numberSystem), \(manufacturer), \(product), \(check).")
case .QRCode(let productCode):
- print("QR code with value of \(productCode).")
+ print("QR code: \(productCode).")
}
-// 输出 "QR code with value of ABCDEFGHIJKLMNOP.”
+// 输出 "QR code: ABCDEFGHIJKLMNOP."
```
如果一个枚举成员的所有相关值被提取为常量,或者它们全部被提取为变量,为了简洁,你可以只放置一个`var`或者`let`标注在成员名称前:
```swift
switch productBarcode {
-case let .UPCA(numberSystem, identifier, check):
- print("UPC-A with value of \(numberSystem), \(identifier), \(check).")
+case let .UPCA(numberSystem, manufacturer, product, check):
+ print("UPC-A: \(numberSystem), \(manufacturer), \(product), \(check).")
case let .QRCode(productCode):
- print("QR code with value of \(productCode).")
+ print("QR code: \(productCode).")
}
-// 输出 "QR code with value of ABCDEFGHIJKLMNOP."
+// 输出 "QR code: ABCDEFGHIJKLMNOP."
```
@@ -228,7 +228,7 @@ let possiblePlanet = Planet(rawValue: 7)
// possiblePlanet is of type Planet? and equals Planet.Uranus
```
-然而,并非所有可能的`Int`值都可以找到一个匹配的行星。正因为如此,构造函数可以返回一个***可选***的枚举成员。在上面的例子中,`possiblePlanet`是`Planet?`类型,或“可选的`Planet`”。
+然而,并非所有可能的`Int`值都可以找到一个匹配的行星。正因为如此,构造函数可以返回一个*可选*的枚举成员。在上面的例子中,`possiblePlanet`是`Planet?`类型,或“可选的`Planet`”。
如果你试图寻找一个位置为9的行星,通过参数为`rawValue`构造函数返回的可选`Planet`值将是`nil`:
From cb01035cd29a9dc3d3c7089def576d28e086d9e7 Mon Sep 17 00:00:00 2001
From: futantan \`。例如,class 不是合法的标识符,但可以使用 \`class\`。反引号不属于标识符的一部分,\`x\` 和 `x` 表示同一标识符。
-
-闭包(*closure*)中如果没有明确指定参数名称,参数将被隐式命名为 $0、$1、$2... 这些命名在闭包作用域内是合法的标识符。
-
-> 标识符语法
-> *标识符* → [*标识符头(Head)*](LexicalStructure.html#identifier_head) [*标识符字符列表*](LexicalStructure.html#identifier_characters) _可选_
-> *标识符* → **`** [*标识符头(Head)*](LexicalStructure.html#identifier_head) [*标识符字符列表*](LexicalStructure.html#identifier_characters) _可选_ **`**
-> *标识符* → [*隐式参数名*](LexicalStructure.html#implicit_parameter_name)
-> *标识符列表* → [*标识符*](LexicalStructure.html#identifier) | [*标识符*](LexicalStructure.html#identifier) **,** [*标识符列表*](LexicalStructure.html#identifier_list)
-> *标识符头(Head)* → Upper- or lowercase letter A through Z
-> *标识符头(Head)* → U+00A8, U+00AA, U+00AD, U+00AF, U+00B2–U+00B5, or U+00B7–U+00BA
-> *标识符头(Head)* → U+00BC–U+00BE, U+00C0–U+00D6, U+00D8–U+00F6, or U+00F8–U+00FF
-> *标识符头(Head)* → U+0100–U+02FF, U+0370–U+167F, U+1681–U+180D, or U+180F–U+1DBF
-> *标识符头(Head)* → U+1E00–U+1FFF
-> *标识符头(Head)* → U+200B–U+200D, U+202A–U+202E, U+203F–U+2040, U+2054, or U+2060–U+206F
-> *标识符头(Head)* → U+2070–U+20CF, U+2100–U+218F, U+2460–U+24FF, or U+2776–U+2793
-> *标识符头(Head)* → U+2C00–U+2DFF or U+2E80–U+2FFF
-> *标识符头(Head)* → U+3004–U+3007, U+3021–U+302F, U+3031–U+303F, or U+3040–U+D7FF
-> *标识符头(Head)* → U+F900–U+FD3D, U+FD40–U+FDCF, U+FDF0–U+FE1F, or U+FE30–U+FE44
-> *标识符头(Head)* → U+FE47–U+FFFD
-> *标识符头(Head)* → U+10000–U+1FFFD, U+20000–U+2FFFD, U+30000–U+3FFFD, or U+40000–U+4FFFD
-> *标识符头(Head)* → U+50000–U+5FFFD, U+60000–U+6FFFD, U+70000–U+7FFFD, or U+80000–U+8FFFD
-> *标识符头(Head)* → U+90000–U+9FFFD, U+A0000–U+AFFFD, U+B0000–U+BFFFD, or U+C0000–U+CFFFD
-> *标识符头(Head)* → U+D0000–U+DFFFD or U+E0000–U+EFFFD
-> *标识符字符* → 数值 0 到 9
-> *标识符字符* → U+0300–U+036F, U+1DC0–U+1DFF, U+20D0–U+20FF, or U+FE20–U+FE2F
-> *标识符字符* → [*标识符头(Head)*](LexicalStructure.html#identifier_head)
-> *标识符字符列表* → [*标识符字符*](LexicalStructure.html#identifier_character) [*标识符字符列表*](LexicalStructure.html#identifier_characters) _可选_
-> *隐式参数名* → **$** [*十进制数字列表*](LexicalStructure.html#decimal_digits)
-
-
-## 关键字
-
-被保留的关键字(*keywords*)不允许用作标识符,除非被反引号转义,参见 [标识符](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/doc/uid/TP40014097-CH30-XID_796)。
-
-* **用作声明的关键字:** *class*、*deinit*、*enum*、*extension*、*func*、*import*、*init*、*let*、*protocol*、*static*、*struct*、*subscript*、*typealias*、*var*
-* **用作语句的关键字:** *break*、*case*、*continue*、*default*、*do*、*else*、*fallthrough*、*if*、*in*、*for*、*return*、*switch*、*where*、*while*
-* **用作表达和类型的关键字:** *as*、*dynamicType*、*is*、*new*、*super*、*self*、*Self*、*Type*、*\_\_COLUMN\_\_*、*\_\_FILE\_\_*、*\_\_FUNCTION\_\_*、*\_\_LINE\_\_*
-* **特定上下文中被保留的关键字:** *associativity*、*didSet*、*get*、*infix*、*inout*、*left*、*mutating*、*none*、*nonmutating*、*operator*、*override*、*postfix*、
- *precedence*、*prefix*、*right*、*set*、*unowned*、*unowned(safe)*、*unowned(unsafe)*、*weak*、*willSet*,这些关键字在特定上下文之外可以被用于标识符。
-
-
-## 字面量
-
-字面值表示整型、浮点型数字或文本类型的值,举例如下:
-
-```swift
-42 // 整型字面量
-3.14159 // 浮点型字面量
-"Hello, world!" // 文本型字面量
-```
-
-> 字面量语法
-> *字面量* → [*整型字面量*](LexicalStructure.html#integer_literal) | [*浮点数字面量*](LexicalStructure.html#floating_point_literal) | [*字符串字面量*](LexicalStructure.html#string_literal)
-
-### 整型字面量
-
-整型字面量(*integer literals*)表示未指定精度整型数的值。整型字面量默认用十进制表示,可以加前缀来指定其他的进制,二进制字面量加 `0b`,八进制字面量加 `0o`,十六进制字面量加 `0x`。
-
-十进制字面量包含数字 `0` 至 `9`。二进制字面量只包含 `0` 或 `1`,八进制字面量包含数字 `0` 至 `7`,十六进制字面量包含数字 `0` 至 `9` 以及字母 `A` 至 `F` (大小写均可)。
-
-负整数的字面量在数字前加减号 `-`,比如 `-42`。
-
-允许使用下划线 `_` 来增加数字的可读性,下划线不会影响字面量的值。整型字面量也可以在数字前加 `0`,同样不会影响字面量的值。
-
-```swift
-1000_000 // 等于 1000000
-005 // 等于 5
-```
-
-除非特殊指定,整型字面量的默认类型为 Swift 标准库类型中的 `Int`。Swift 标准库还定义了其他不同长度以及是否带符号的整数类型,请参考 [整数类型](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/TheBasics.html#//apple_ref/doc/uid/TP40014097-CH5-XID_411)。
-
-> 整型字面量语法
-> *整型字面量* → [*二进制字面量*](LexicalStructure.html#binary_literal)
-> *整型字面量* → [*八进制字面量*](LexicalStructure.html#octal_literal)
-> *整型字面量* → [*十进制字面量*](LexicalStructure.html#decimal_literal)
-> *整型字面量* → [*十六进制字面量*](LexicalStructure.html#hexadecimal_literal)
-> *二进制字面量* → **0b** [*二进制数字*](LexicalStructure.html#binary_digit) [*二进制字面量字符列表*](LexicalStructure.html#binary_literal_characters) _可选_
-> *二进制数字* → 数值 0 到 1
-> *二进制字面量字符* → [*二进制数字*](LexicalStructure.html#binary_digit) | **_**
-> *二进制字面量字符列表* → [*二进制字面量字符*](LexicalStructure.html#binary_literal_character) [*二进制字面量字符列表*](LexicalStructure.html#binary_literal_characters) _可选_
-> *八进制字面量* → **0o** [*八进字数字*](LexicalStructure.html#octal_digit) [*八进制字符列表*](LexicalStructure.html#octal_literal_characters) _可选_
-> *八进字数字* → 数值 0 到 7
-> *八进制字符* → [*八进字数字*](LexicalStructure.html#octal_digit) | **_**
-> *八进制字符列表* → [*八进制字符*](LexicalStructure.html#octal_literal_character) [*八进制字符列表*](LexicalStructure.html#octal_literal_characters) _可选_
-> *十进制字面量* → [*十进制数字*](LexicalStructure.html#decimal_digit) [*十进制字符列表*](LexicalStructure.html#decimal_literal_characters) _可选_
-> *十进制数字* → 数值 0 到 9
-> *十进制数字列表* → [*十进制数字*](LexicalStructure.html#decimal_digit) [*十进制数字列表*](LexicalStructure.html#decimal_digits) _可选_
-> *十进制字符* → [*十进制数字*](LexicalStructure.html#decimal_digit) | **_**
-> *十进制字符列表* → [*十进制字符*](LexicalStructure.html#decimal_literal_character) [*十进制字符列表*](LexicalStructure.html#decimal_literal_characters) _可选_
-> *十六进制字面量* → **0x** [*十六进制数字*](LexicalStructure.html#hexadecimal_digit) [*十六进制字面量字符列表*](LexicalStructure.html#hexadecimal_literal_characters) _可选_
-> *十六进制数字* → 数值 0 到 9, a through f, or A through F
-> *十六进制字符* → [*十六进制数字*](LexicalStructure.html#hexadecimal_digit) | **_**
-> *十六进制字面量字符列表* → [*十六进制字符*](LexicalStructure.html#hexadecimal_literal_character) [*十六进制字面量字符列表*](LexicalStructure.html#hexadecimal_literal_characters) _可选_
-
-### 浮点型字面量
-
-浮点型字面量(*floating-point literals*)表示未指定精度浮点数的值。
-
-浮点型字面量默认用十进制表示(无前缀),也可以用十六进制表示(加前缀 `0x`)。
-
-十进制浮点型字面量(*decimal floating-point literals*)由十进制数字串后跟小数部分或指数部分(或两者皆有)组成。十进制小数部分由小数点 `.` 后跟十进制数字串组成。指数部分由大写或小写字母 `e` 后跟十进制数字串组成,这串数字表示 `e` 之前的数量乘以 10 的几次方。例如:`1.25e2` 表示 `1.25 ⨉ 10^2`,也就是 `125.0`;同样,`1.25e-2` 表示 `1.25 ⨉ 10^-2`,也就是 `0.0125`。
-
-十六进制浮点型字面量(*hexadecimal floating-point literals*)由前缀 `0x` 后跟可选的十六进制小数部分以及十六进制指数部分组成。十六进制小数部分由小数点后跟十六进制数字串组成。指数部分由大写或小写字母 `p` 后跟十进制数字串组成,这串数字表示 `p` 之前的数量乘以 2 的几次方。例如:`0xFp2` 表示 `15 ⨉ 2^2`,也就是 `60`;同样,`0xFp-2` 表示 `15 ⨉ 2^-2`,也就是 `3.75`。
-
-与整型字面量不同,负的浮点型字面量由一元运算符减号 `-` 和浮点型字面量组成,例如 `-42.0`。这代表一个表达式,而不是一个浮点整型字面量。
-
-允许使用下划线 `_` 来增强可读性,下划线不会影响字面量的值。浮点型字面量也可以在数字前加 `0`,同样不会影响字面量的值。
-
-```swift
-10_000.56 // 等于 10000.56
-005000.76 // 等于 5000.76
-```
-
-除非特殊指定,浮点型字面量的默认类型为 Swift 标准库类型中的 `Double`,表示64位浮点数。Swift 标准库也定义 `Float` 类型,表示32位浮点数。
-
-> 浮点型字面量语法
-> *浮点数字面量* → [*十进制字面量*](LexicalStructure.html#decimal_literal) [*十进制分数*](LexicalStructure.html#decimal_fraction) _可选_ [*十进制指数*](LexicalStructure.html#decimal_exponent) _可选_
-> *浮点数字面量* → [*十六进制字面量*](LexicalStructure.html#hexadecimal_literal) [*十六进制分数*](LexicalStructure.html#hexadecimal_fraction) _可选_ [*十六进制指数*](LexicalStructure.html#hexadecimal_exponent)
-> *十进制分数* → **.** [*十进制字面量*](LexicalStructure.html#decimal_literal)
-> *十进制指数* → [*浮点数e*](LexicalStructure.html#floating_point_e) [*正负号*](LexicalStructure.html#sign) _可选_ [*十进制字面量*](LexicalStructure.html#decimal_literal)
-> *十六进制分数* → **.** [*十六进制字面量*](LexicalStructure.html#hexadecimal_literal) _可选_
-> *十六进制指数* → [*浮点数p*](LexicalStructure.html#floating_point_p) [*正负号*](LexicalStructure.html#sign) _可选_ [*十六进制字面量*](LexicalStructure.html#hexadecimal_literal)
-> *浮点数e* → **e** | **E**
-> *浮点数p* → **p** | **P**
-> *正负号* → **+** | **-**
-
-### 文本型字面量
-
-文本型字面量(*string literal*)由双引号中的字符串组成,形式如下:
-
-```swift
-"characters"
-```
-
-文本型字面量中不能包含未转义的双引号 `"`、未转义的反斜线`\`、回车符(*carriage return*)或换行符(*line feed*)。
-
-可以在文本型字面量中使用的转义特殊符号如下:
-
-* 空字符(Null Character)`\0`
-* 反斜线(Backslash)`\\`
-* 水平 Tab (Horizontal Tab)`\t`
-* 换行符(Line Feed)`\n`
-* 回车符(Carriage Return)`\r`
-* 双引号(Double Quote)`\"`
-* 单引号(Single Quote)`\'`
-
-字符也可以用以下方式表示:
-
-* `\x` 后跟两位十六进制数字
-* `\u` 后跟四位十六进制数字
-* `\U` 后跟八位十六进制数字
-
-后跟的数字表示一个 Unicode 码点。
-
-文本型字面量允许在反斜线小括号 `\()` 中插入表达式的值。插入表达式(*interpolated expression*)不能包含未转义的双引号 `"`、反斜线 `\`、回车符或者换行符。表达式值的类型必须在 *String* 类中有对应的初始化方法。
-
-例如,以下所有文本型字面量的值相同:
-
-```swift
-"1 2 3"
-"1 2 \(3)"
-"1 2 \(1 + 2)"
-var x = 3; "1 2 \(x)"
-```
-
-文本型字面量的默认类型为 `String`。组成字符串的字符类型为 `Character`。更多有关 `String` 和 `Character` 的信息请参照 [字符串和字符](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/StringsAndCharacters.html#//apple_ref/doc/uid/TP40014097-CH7-XID_368)。
-
-> 字符型字面量语法
-> *字符串字面量* → **"** [*引用文本*](LexicalStructure.html#quoted_text) **"**
-> *引用文本* → [*引用文本条目*](LexicalStructure.html#quoted_text_item) [*引用文本*](LexicalStructure.html#quoted_text) _可选_
-> *引用文本条目* → [*转义字符*](LexicalStructure.html#escaped_character)
-> *引用文本条目* → **\(** [*表达式*](..\chapter3\04_Expressions.html#expression) **)**
-> *引用文本条目* → 除了", \, U+000A, or U+000D的所有Unicode的字符
-> *转义字符* → **\0** | **\\** | **\t** | **\n** | **\r** | **\"** | **\'**
-> *转义字符* → **\x** [*十六进制数字*](LexicalStructure.html#hexadecimal_digit) [*十六进制数字*](LexicalStructure.html#hexadecimal_digit)
-> *转义字符* → **\u** [*十六进制数字*](LexicalStructure.html#hexadecimal_digit) [*十六进制数字*](LexicalStructure.html#hexadecimal_digit) [*十六进制数字*](LexicalStructure.html#hexadecimal_digit) [*十六进制数字*](LexicalStructure.html#hexadecimal_digit)
-> *转义字符* → **\U** [*十六进制数字*](LexicalStructure.html#hexadecimal_digit) [*十六进制数字*](LexicalStructure.html#hexadecimal_digit) [*十六进制数字*](LexicalStructure.html#hexadecimal_digit) [*十六进制数字*](LexicalStructure.html#hexadecimal_digit) [*十六进制数字*](LexicalStructure.html#hexadecimal_digit) [*十六进制数字*](LexicalStructure.html#hexadecimal_digit) [*十六进制数字*](LexicalStructure.html#hexadecimal_digit) [*十六进制数字*](LexicalStructure.html#hexadecimal_digit)
-
-
-## 运算符
-
-Swift 标准库定义了许多可供使用的运算符,其中大部分在 [基础运算符](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/BasicOperators.html#//apple_ref/doc/uid/TP40014097-CH6-XID_70) 和 [高级运算符](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/AdvancedOperators.html#//apple_ref/doc/uid/TP40014097-CH27-XID_28) 中进行了阐述。这里将描述哪些字符能用作运算符。
-
-运算符由一个或多个以下字符组成:
-`/`、`=`、`-`、`+`、`!`、`*`、`%`、`<`、`>`、`&`、`|`、`^`、`~`、`.`。也就是说,标记 `=`, `->`、`//`、`/*`、`*/`、`.` 以及一元前缀运算符 `&` 属于保留字,这些标记不能被重写或用于自定义运算符。
-
-运算符两侧的空白被用来区分该运算符是否为前缀运算符(*prefix operator*)、后缀运算符(*postfix operator*)或二元运算符(*binary operator*)。规则总结如下:
-
-* 如果运算符两侧都有空白或两侧都无空白,将被看作二元运算符。例如:`a+b` 和 `a + b` 中的运算符 `+` 被看作二元运算符。
-* 如果运算符只有左侧空白,将被看作前缀一元运算符。例如 `a ++b` 中的 `++` 被看作前缀一元运算符。
-* 如果运算符只有右侧空白,将被看作后缀一元运算符。例如 `a++ b` 中的 `++` 被看作后缀一元运算符。
-* 如果运算符左侧没有空白并紧跟 `.`,将被看作后缀一元运算符。例如 `a++.b` 中的 `++` 被看作后缀一元运算符(同理, `a++ . b` 中的 `++` 是后缀一元运算符而 `a ++ .b` 中的 `++` 不是).
-
-鉴于这些规则,运算符前的字符 `(`、`[` 和 `{` ;运算符后的字符 `)`、`]` 和 `}` 以及字符 `,`、`;` 和 `:` 都将用于空白检测。
-
-以上规则需注意一点,如果运算符 `!` 或 `?` 左侧没有空白,则不管右侧是否有空白都将被看作后缀运算符。如果将 `?` 用作可选类型(*optional type*)修饰,左侧必须无空白。如果用于条件运算符 `? :`,必须两侧都有空白。
-
-在特定构成中 ,以 `<` 或 `>` 开头的运算符会被分离成两个或多个标记,剩余部分以同样的方式会被再次分离。因此,在 `Dictionary\`class\`。反引号不属于标识符的一部分,\`x\` 和 `x` 表示同一标识符。
+
+闭包(*closure*)中如果没有明确指定参数名称,参数将被隐式命名为 `$0`、`$1`、`$2`等等。 这些命名在闭包作用域范围内是合法的标识符。
+
+> 标识符语法
+
+> *标识符* → [*头部标识符*](#identifier_head) [*标识符字符组*](#identifier_characters)可选
+> *标识符* → \`[*头部标识符*](#identifier_head) [*标识符字符组*](#identifier_characters)可选\`
+> *标识符* → [*隐式参数名*](#implicit_parameter_name)
+> *标识符列表* → [*标识符*](#identifier) | [*标识符*](#identifier) **,** [*标识符列表*](#identifier_list)
+
+> *头部标识符* → 大写或小写字母 A - Z
+> *头部标识符* → U+00A8, U+00AA, U+00AD, U+00AF, U+00B2–U+00B5, or U+00B7–U+00BA
+> *头部标识符* → U+00BC–U+00BE, U+00C0–U+00D6, U+00D8–U+00F6, or U+00F8–U+00FF
+> *头部标识符* → U+0100–U+02FF, U+0370–U+167F, U+1681–U+180D, or U+180F–U+1DBF
+> *头部标识符* → U+1E00–U+1FFF
+> *头部标识符* → U+200B–U+200D, U+202A–U+202E, U+203F–U+2040, U+2054, or U+2060–U+206F
+> *头部标识符* → U+2070–U+20CF, U+2100–U+218F, U+2460–U+24FF, or U+2776–U+2793
+> *头部标识符* → U+2C00–U+2DFF or U+2E80–U+2FFF
+> *头部标识符* → U+3004–U+3007, U+3021–U+302F, U+3031–U+303F, or U+3040–U+D7FF
+> *头部标识符* → U+F900–U+FD3D, U+FD40–U+FDCF, U+FDF0–U+FE1F, or U+FE30–U+FE44
+> *头部标识符* → U+FE47–U+FFFD
+> *头部标识符* → U+10000–U+1FFFD, U+20000–U+2FFFD, U+30000–U+3FFFD, or U+40000–U+4FFFD
+> *头部标识符* → U+50000–U+5FFFD, U+60000–U+6FFFD, U+70000–U+7FFFD, or U+80000–U+8FFFD
+> *头部标识符* → U+90000–U+9FFFD, U+A0000–U+AFFFD, U+B0000–U+BFFFD, or U+C0000–U+CFFFD
+> *头部标识符* → U+D0000–U+DFFFD or U+E0000–U+EFFFD
+> *标识符字符* → 数值 0 - 9
+> *标识符字符* → U+0300–U+036F, U+1DC0–U+1DFF, U+20D0–U+20FF, or U+FE20–U+FE2F
+> *标识符字符* → [*头部标识符*](#identifier_head)
+
+> *标识符字符组* → [*标识符字符*](#identifier_character) [*标识符字符列表*](#identifier_characters)可选
+
+## 关键字和符号
+
+下面这些被保留的关键字(*keywords*)不允许用作标识符,除非被反引号转义,具体描述请参考 [标识符](#identifiers)。
+
+* **用在声明中的关键字:** *class*、*deinit*、*enum*、*extension*、*func*、*import*、*init*、*let*、*protocol*、*static*、*struct*、*subscript*、*typealias*、*var*
+* **用在语句中的关键字:** *break*、*case*、*continue*、*default*、*do*、*else*、*fallthrough*、*if*、*in*、*for*、*return*、*switch*、*where*、*while*
+* **用在表达式和类型中的关键字:** *as*、*dynamicType*、*is*、*new*、*super*、*self*、*Self*、*Type*、*\_\_COLUMN\_\_*、*\_\_FILE\_\_*、*\_\_FUNCTION\_\_*、*\_\_LINE\_\_*
+* **用在模式中的关键字:** *\_*
+* **特定上下文中被保留的关键字:** *associativity*、*didSet*、*get*、*infix*、*inout*、*left*、*mutating*、*none*、*nonmutating*、*operator*、*override*、*postfix*、*precedence*、*prefix*、*right*、*set*、*unowned*、*unowned(safe)*、*unowned(unsafe)*、*weak*、*willSet*,这些关键字在特定上下文之外可以被用于标识符。
+
+以下标记被当作保留符号,不能用于自定义操作符:`(`、`)`、`{`、`}`、`[`、`]`、`.`、`,`、`:`、`;`、`=`、`@`、`#`、`&(作为前缀操作符)`、`->`、`` `、`?` 和 `!(作为后缀操作符)`。
+
+
+## 字面量
+
+字面量是用来表示源码中某种特定类型的值,比如一个数字或字符串。
+
+下面是字面量的一些示例:
+
+```swift
+42 // 整型字面量
+3.14159 // 浮点型字面量
+"Hello, world!" // 字符串型字面量
+true // 布尔型字面量
+```
+
+字面量本身并不包含类型信息。事实上,一个字面量会被解析为拥有无限的精度,然后 Swift 的类型推导会尝试去推导出这个字面量的类型。比如,在 `let x: Int8 = 42` 这个声明中,Swift 使用了显式类型注解(`: Int8`)来推导出 `42` 这个整型字面量的类型是 `Int8`。如果没有可用的类型信息, Swift 则会从标准库中定义的字面量类型中推导出一个默认的类型。整型字面量的默认类型是 `Int`,浮点型字面量的默认类型是 `Double`,字符串型字面量的默认类型是 `String`,布尔型字面量的默认类型是 `Bool`。比如,在 `let str = "Hello, world"` 这个声明中,字符串 `"Hello, world"`的默认推导类型就是 `String`。
+
+当为一个字面量值指定了类型注解的时候,这个注解的类型必须能通过这个字面量值实例化后得到。也就是说,这个类型必须遵守这些 Swift 标准库协议中的一个:整型字面量的`IntegerLiteralConvertible`协议、符点型字面量的`FloatingPointLiteralConvertible`协议、字符串字面量的`StringLiteralConvertible`协议以及布尔型字面量的`BooleanLiteralConvertible`协议。比如,`Int8` 遵守了 `IntegerLiteralConvertible`协议,因此它能在 `let x: Int8 = 42` 这个声明中作为整型字面量 `42` 的类型注解。
+
+> 字面量语法
+> *字面量* → [*数字型字面量*](#numeric_literal) | [*字符串型字面量*](#string_literal) | [*布尔型字面量*](#boolean_literal) | [*nil型字面量*](#nil_literal)
+
+> *数字型字面量* → -可选[*整型字面量*](#integer_literal) | -可选[*符点型字面量*](#floating_point_literal)
+> *布尔型字面量* → **true** | **false**
+> *nil型字面量* → **nil**
+
+### 整型字面量
+
+整型字面量(*integer literals*)表示未指定精度整型数的值。整型字面量默认用十进制表示,可以加前缀来指定其他的进制,二进制字面量加 `0b`,八进制字面量加 `0o`,十六进制字面量加 `0x`。
+
+十进制字面量包含数字 `0` 至 `9`。二进制字面量只包含 `0` 或 `1`,八进制字面量包含数字 `0` 至 `7`,十六进制字面量包含数字 `0` 至 `9` 以及字母 `A` 至 `F` (大小写均可)。
+
+负整数的字面量在整型字面量前加减号 `-`,比如 `-42`。
+
+整型字面面可以使用下划线 `_` 来增加数字的可读性,下划线会被系统忽略,因此不会影响字面量的值。同样地,也可以在数字前加 `0`,并不会影响字面量的值。
+
+除非特别指定,整型字面量的默认推导类型为 Swift 标准库类型中的 `Int`。Swift 标准库还定义了其他不同长度以及是否带符号的整数类型,请参考 [整数类型](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/TheBasics.html#//apple_ref/doc/uid/TP40014097-CH5-ID323)。
+
+> 整型字面量语法
+> *整型字面量* → [*二进制字面量*](#binary_literal)
+> *整型字面量* → [*八进制字面量*](#octal_literal)
+> *整型字面量* → [*十进制字面量*](#decimal_literal)
+> *整型字面量* → [*十六进制字面量*](#hexadecimal_literal)
+
+> *二进制字面量* → **0b** [*二进制数字*](#binary_digit) [*二进制字面量字符组*](#binary_literal_characters)可选
+> *二进制数字* → 数值 0 到 1
+> *二进制字面量字符* → [*二进制数字*](#binary_digit) | _
+> *二进制字面量字符组* → [*二进制字面量字符*](#binary_literal_character) [*二进制字面量字符组*](#binary_literal_characters)可选
+
+> *十进制字面量* → [*十进制数字*](#decimal_digit) [*十进制字符组*](#decimal_literal_characters)可选
+> *十进制数字* → 数值 0 到 9
+> *十进制数字列表* → [*十进制数字*](#decimal_digit) [*十进制数字列表*](#decimal_digits)可选
+> *十进制字符* → [*十进制数字*](#decimal_digit) | _
+> *十进制字符列表* → [*十进制字符*](#decimal_literal_character) [*十进制字符列表*](#decimal_literal_characters)可选
+
+> *十六进制字面量* → **0x** [*十六进制数字*](#hexadecimal_digit) [*十六进制字面量字符列表*](#hexadecimal_literal_characters)可选
+> *十六进制数字* → 数值 0 到 9, 字母 a 到 f, 或 A 到 F
+> *十六进制字符* → [*十六进制数字*](#hexadecimal_digit) | _
+> *十六进制字面量字符列表* → [*十六进制字符*](#hexadecimal_literal_character) [*十六进制字面量字符列表*](#hexadecimal_literal_characters)可选
+
+### 浮点型字面量
+
+浮点型字面量(*floating-point literals*)表示未指定精度浮点数的值。
+
+浮点型字面量默认用十进制表示(无前缀),也可以用十六进制表示(加前缀 `0x`)。
+
+十进制浮点型字面量(*decimal floating-point literals*)由十进制数字串后跟小数部分或指数部分(或两者皆有)组成。十进制小数部分由小数点 `.` 后跟十进制数字串组成。指数部分由大写或小写字母 `e` 为前缀后跟十进制数字串组成,这串数字表示 `e` 之前的数量乘以 10 的几次方。例如:`1.25e2` 表示 `1.25 ⨉ 10^2`,也就是 `125.0`;同样,`1.25e-2` 表示 `1.25 ⨉ 10^-2`,也就是 `0.0125`。
+
+十六进制浮点型字面量(*hexadecimal floating-point literals*)由前缀 `0x` 后跟可选的十六进制小数部分以及十六进制指数部分组成。十六进制小数部分由小数点后跟十六进制数字串组成。指数部分由大写或小写字母 `p` 为前缀后跟十进制数字串组成,这串数字表示 `p` 之前的数量乘以 2 的几次方。例如:`0xFp2` 表示 `15 ⨉ 2^2`,也就是 `60`;同样,`0xFp-2` 表示 `15 ⨉ 2^-2`,也就是 `3.75`。
+
+负的浮点型字面量由一元运算符减号 `-` 和浮点型字面量组成,例如 `-42.5`。
+
+浮点型字面量允许使用下划线 `_` 来增强数字的可读性,下划线会被系统忽略,因此不会影响字面量的值。同样地,也可以在数字前加 `0`,并不会影响字面量的值。
+
+除非特别指定,浮点型字面量的默认推导类型为 Swift 标准库类型中的 `Double`,表示64位浮点数。Swift 标准库也定义了 `Float` 类型,表示32位浮点数。
+
+> 浮点型字面量语法
+> *浮点数字面量* → [*十进制字面量*](#decimal_literal) [*十进制分数*](#decimal_fraction)可选 [*十进制指数*](#decimal_exponent)可选
+> *浮点数字面量* → [*十六进制字面量*](#hexadecimal_literal) [*十六进制分数*](#hexadecimal_fraction)可选 [*十六进制指数*](#hexadecimal_exponent)
+
+> *十进制分数* → **.** [*十进制字面量*](#decimal_literal)
+> *十进制指数* → [*浮点数e*](#floating_point_e) [*正负号*](#sign)可选 [*十进制字面量*](#decimal_literal)
+
+> *十六进制分数* → **.** [*十六进制数字*](#hexadecimal_digit) [*十六进制字面量字符列表*](#hexadecimal_literal_characters)可选
+> *十六进制指数* → [*浮点数p*](#floating_point_p) [*正负号*](#sign)可选 [*十进制字面量*](#decimal_literal)
+
+> *浮点数e* → **e** | **E**
+> *浮点数p* → **p** | **P**
+> *正负号* → **+** | **-**
+
+
+### 字符串型字面量
+
+字符串型字面量(*string literal*)由被包在双引号中的一串字符组成,形式如下:
+
+```
+"characters"
+```
+
+字符串型字面量中不能包含未转义的双引号 (`"`)、未转义的反斜线(`\`)、回车符(*carriage return*)或换行符(*line feed*)。
+
+可以在字符串字面量中使用的转义特殊符号如下:
+
+* 空字符(Null Character)`\0`
+* 反斜线(Backslash)`\\`
+* 水平制表符(Horizontal Tab)`\t`
+* 换行符(Line Feed)`\n`
+* 回车符(Carriage Return)`\r`
+* 双引号(Double Quote)`\"`
+* 单引号(Single Quote)`\'`
+* Unicode标量 `\u{n}`,n为一到八位的十六进制数字
+
+字符串字面量允许在反斜杠小括号 `\()` 中插入表达式的值。插入表达式(*interpolated expression*)不能包含未转义的双引号 `"`、未转义的反斜线 `\`、回车符或者换行符。表达式结果的类型必须在 *String* 类中有对应的初始化方法。
+
+例如,以下所有字符串字面量的值都是相同的:
+
+```
+"1 2 3"
+"1 2 \(3)"
+"1 2 \(1 + 2)"
+let x = 3; "1 2 \(x)"
+```
+
+字符串字面量的默认推导类型为 `String`。组成字符串的字符默认推导类型为 `Character`。更多有关 `String` 和 `Character` 的信息请参照 [字符串和字符](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/StringsAndCharacters.html#//apple_ref/doc/uid/TP40014097-CH7-XID_368)。
+
+> 字符型字面量语法
+> *字符串字面量* → **"** [*引用文本*](#quoted_text)可选 **"**
+
+> *引用文本* → [*引用文本条目*](#quoted_text_item) [*引用文本*](#quoted_text) 可选
+> *引用文本条目* → [*转义字符*](#escaped_character)
+> *引用文本条目* → **\(** [*表达式*](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Expressions.html#//apple_ref/doc/uid/TP40014097-CH32-ID383) **)**
+> *引用文本条目* → **除了", \, U+000A, 或者 U+000D的所有Unicode的字符**
+> *转义字符* → **\0** | **\\** | **\t** | **\n** | **\r** | **\"** | **\'**
+> *转义字符* → **\u {** [*unicode标量数字*](#unicode_scalar_digits) **}**
+> *unicode标量数字* → 一到八位的十六进制数字
+
+
+## 运算符
+
+Swift 标准库定义了许多可供使用的运算符,其中大部分在 [基础运算符](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/BasicOperators.html#//apple_ref/doc/uid/TP40014097-CH6-XID_70) 和 [高级运算符](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/AdvancedOperators.html#//apple_ref/doc/uid/TP40014097-CH27-XID_28) 中进行了阐述。这一小节将描述哪些字符能用于自定义运算符。
+
+自定义运算符可以由以下其中之一的 ASCII 字符 `/`、`=`、 `-`、`+`、`!`、`*`、`%`、`<`、`>`、`&`、`|`、`^`、`?` 以及 `~`, 或者后面语法中规定的任一个 Unicode 字符开始。在第一个字符之后,允许使用组合型 Unicode 字符。也可以使用两个或者多个的点号来自定义运算符(比如, `....`)。虽然可以自定义包含问号`?`的运算符,但是这个运算符不能只包含单独的一个问号。
+
+ 注意:
+ 以下这些标记 =, ->, //, /*, */, ., <(前缀运算符), &, and ?, ?(中缀运算符), >(后缀运算符), ! 以及 ? 是被系统保留的。这些标记不能被重载,也不能用于自定义操作符。
+
+运算符两侧的空白被用来区分该运算符是否为前缀运算符(*prefix operator*)、后缀运算符(*postfix operator*)或二元运算符(*binary operator*)。规则总结如下:
+
+* 如果运算符两侧都有空白或两侧都无空白,将被看作二元运算符。例如:`a+b` 和 `a + b` 中的运算符 `+` 被看作二元运算符。
+* 如果运算符只有左侧空白,将被看作前缀一元运算符。例如 `a ++b` 中的 `++` 被看作前缀一元运算符。
+* 如果运算符只有右侧空白,将被看作后缀一元运算符。例如 `a++ b` 中的 `++` 被看作后缀一元运算符。
+* 如果运算符左侧没有空白并紧跟 `.`,将被看作后缀一元运算符。例如 `a++.b` 中的 `++` 被看作后缀一元运算符(即上式被视为 `a++ .b` 而非 `a ++ .b`)。
+
+鉴于这些规则,运算符前的字符 `(`、`[` 和 `{` ;运算符后的字符 `)`、`]` 和 `}` 以及字符 `,`、`;` 和 `:` 都被视为空白。
+
+以上规则需注意一点,如果预定义运算符 `!` 或 `?` 左侧没有空白,则不管右侧是否有空白都将被看作后缀运算符。如果将 `?` 用作可选链(*optional-chaining*)操作符,左侧必须无空白。如果用于条件运算符 `? :`,必须两侧都有空白。
+
+在某些特定的构造中 ,以 `<` 或 `>` 开头的运算符会被分离成两个或多个标记,剩余部分以同样的方式会被再次分离。因此,在 `Dictionary`introduced=version number`
这里的`version number`由一个正的十进制整数或浮点数构成。 +- `iOS` +- `iOSApplicationExtension` +- `OSX` +- `OSXApplicationExtension` +- `watchOS` -- `deprecated`参数表示:特定的平台上,该声明被建议弃用的第一个版本。格式如下: +当然,你也可以用一个星号(*)来表示,该声明在上面提到的所有平台上都是有效的。 + +剩下的参数,可以以任何顺序出现,并且可以添加关于声明生命周期的附加信息,包括重要的里程碑。 + +- `unavailable`参数表示:该声明在特定的平台上是无效的 + +- `introduced`参数表示:该声明第一次被引入时所在平台的版本。格式如下: +
`introduced=version number`
这里的`version number`由一个正的十进制整数或浮点数构成。 + +- `deprecated`参数表示:该声明第一次被建议弃用时所在平台的版本。格式如下:
`deprecated=version number`
这里的`version number`由一个正的十进制整数或浮点数构成。 -- `obsoleted`参数表示:特定的平台上,该声明被弃用的第一个版本。格式如下: -
`deprecated=version number`
这里的`version number`由一个正的十进制整数或浮点数构成。 +- `obsoleted`参数表示:该声明第一次被弃用时所在平台的版本。当一个声明被弃用时,它就从此平台中被移除,不能再被使用。格式如下: +
`obsoleted=version number`
这里的`version number`由一个正的十进制整数或浮点数构成。 -- `message`参数用来提供文本信息,并在因使用建议弃用或者被弃用的声明而遇到警告或错误时,由编译器抛出。格式如下: +- `message`参数用来提供文本信息。当使用建议弃用或者被弃用的声明时,编译器会抛出错误或警告信息。格式如下:
`message=message`
这里的`message`由一个字符串文字构成。 -- `renamed`参数用来提供文本信息,用以表示被重命名的声明的新名字。当使用这个重命名的声明遇到错误时,该新名字会被编译器显示出来。格式如下: +- `renamed`参数用来提供文本信息,用以表示被重命名的声明的新名字。当使用这个重命名的声明遇到错误时,编译器会显示出该新名字。格式如下:
`renamed=new name`
这里的`new name`由一个字符串文字构成。 -你可以将`renamed`参数和`unavailable`参数以及类型别名声明组合使用,以向用户表示:在你的代码中,一个声明已经被重命名。当一个声明的名字在一个框架或者库的不同发布版本间发生变化时,这会相当管用。 +你可以将`renamed`参数和`unavailable`参数以及类型别名声明组合使用,以向用户表示:在你的代码中,一个声明已经被重命名。当一个声明的名字在一个框架或者库的不同发布版本间发生变化时,这会相当有用。 ```swift // First release @@ -58,50 +72,34 @@ protocol MyRenamedProtocol { // protocol definition } -@availability(*, unavailable, renamed="MyRenamedProtocol") +@available(*, unavailable, renamed="MyRenamedProtocol") typealias MyProtocol = MyRenamedProtocol ``` -你可以在一个单独的声明上使用多个`availability`特性,以详细说明该声明在不同平台上的有效性。编译器只有在当前的目标平台和`availability`特性中指定的平台匹配时,才会使用`availability`特性 +你可以在一个单独的声明上使用多个`available`特性,以详细说明该声明在不同平台上的有效性。编译器只有在当前的目标平台和`available`特性中指定的平台匹配时,才会使用`available`特性 -`autoclosure` +如果`available`特性除了平台名称参数外,只指定了一个`introduced `参数,那么可以使用以下简写语法代替: -这个属性通过把表达式自动封装成不带参数的闭包来延迟表达式的计算。这个属性使用在函数参数声明或者不带参数但是返回表达式类型的方法类型上。含有```autoclosure```属性的声明同时也具有```noescape```的特性,除非传递一个可选的参数属性```escaping```,请看[函数类型](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Types.html#//apple_ref/doc/uid/TP40014097-CH31-ID449)。 +@available(`platform name` `version number`, *) -`noescape` - -在函数或者方法声明上使用该属性表示参数将不会被存储用作后续的计算,其用来确保不会超出函数调用的声明周期。使用```noescape```声明属性的函数类型不需要显式的使用```self```,对于其属性或者方法来说。 - -`noreturn` - -该特性用于修饰函数或方法声明,表明该函数或方法的对应类型,`T`,是`@noreturn T`。你可以用这个特性修饰函数或方法的类型,这样一来,函数或方法就不会返回到它的调用者中去。 - -对于一个没有用`noreturn`特性标记的函数或方法,你可以将它重写(override)为用该特性标记的。相反,对于一个已经用`noreturn`特性标记的函数或方法,你则不可以将它重写为没使用该特性标记的。相同的规则试用于当你在一个comforming类型中实现一个协议方法时。 - -`NSApplicationMain` -在类上使用该属性表示该类是应用程序委托类,使用该属性与调用```NSApplicationMain```函数并且把该类的名字作为委托类的名字传递给函数的效果相同。 - -如果你不想使用这个属性,可以提供一个```main.swift```文件,并且提供一个```main```函数去调用```NSApplicationMain```函数。比如,如果你的应用程序使用一个派生于```NSApplication```的自定义子类作为主要类,你可以调用```NSApplicationMain```函数而不是使用该属性。 - - -`NSCopying` - -该特性用于修饰一个类的存储型变量属性。该特性将使属性的setter与属性值的一个副本合成,由`copyWithZone`方法返回,而不是属性本身的值。该属性的类型必需遵循`NSCopying`协议。 - -`NSCopying`特性的行为与Objective-C中的`copy`特性相似。 - -`NSManaged` - -该特性用于修饰`NSManagedObject`子类中的存储型变量属性,表明属性的存储和实现由Core Data在运行时基于相关实体描述动态提供。 +`available`特性的简写语法可以简明地表达出多个平台的可用性。尽管这两种形式在功能上是相同的,但请尽可能地使用简明语法形式。 +```swift +@available(iOS 8.0, OSX 10.10, *) +class MyClass { + // class definition +} +``` `objc` -该特性用于修饰任意可以在Objective-C中表示的声明,比如,非嵌套类,协议,类和协议中的属性和方法(包含getter和setter),初始化器,析构器,以及下标。`objc`特性告诉编译器该声明可以在Objective-C代码中使用。 +该特性用于修饰任何可以在Objective-C中表示的声明。比如,非嵌套类、协议、非泛型枚举(仅限整型值类型)、类和协议的属性和方法(包括`getter`和`setter`)、构造器、析构器以及下标。`objc`特性告诉编译器这个声明可以在Objective-C代码中使用。 -如果你将`objc`特性应用于一个类或协议,它也会隐式地应用于那个类或协议的成员。对于标记了`objc`特性的类,编译器会隐式地为它的子类添加`objc`特性。标记了`objc`特性的协议不能继承自没有标记`objc`的协议。 +如果你将`objc`特性应用于一个类或协议,它也会隐式地应用于那个类的成员或协议。对于标记了`objc`特性的类,编译器会隐式地为它的子类添加`objc`特性。标记了`objc`特性的协议不能继承没有标记`objc`的协议。 -`objc`特性有一个可选的参数,由标记符组成。当你想把`objc`所修饰的实体以一个不同的名字暴露给Objective-C,你就可以使用这个特性参数。你可以使用这个参数来命名类,协议,方法,getters,setters,以及初始化器。下面的例子把`ExampleClass`中`enabled`属性的getter暴露给Objective-C,名字是`isEnabled`,而不是它原来的属性名。 +如果你将`objc`特性应用于枚举,每一个枚举的`case`都会以枚举名称和`case`名称组合的方式暴露在Objective-C代码中。例如:一个名为`Venus`的`case`在`Planet`枚举中,这个`case`暴露在Objective-C代码中时叫做`PlanetVenus`。 + +`objc`特性有一个可选的参数,由标记符组成。当你想把`objc`所修饰的实体以一个不同的名字暴露给Objective-C时,你就可以使用这个特性参数。你可以使用这个参数来命名类,协议,方法,getters,setters,以及构造器。下面的例子把`ExampleClass`中`enabled`属性的getter暴露给Objective-C,名字是`isEnabled`,而不是它原来的属性名。 ```swift @objc @@ -114,17 +112,64 @@ class ExampleClass { } ``` -`optional` +`noescape` -用该特性修饰协议的属性,方法或下标成员,表示实现这些成员并不需要一致性类型(conforming type)。 +在函数或者方法声明上使用该特性,它表示参数将不会被存储用作后续的计算,其用来确保不会超出函数调用的生命周期。对于其属性或方法来说,使用`noescape`声明属性的函数类型不需要显式的使用`self.`。 -你只能用`optional`特性修饰那些标记了`objc`特性的协议。因此,只有类类型可以adopt和comform to那些包含可选成员需求的协议。更多关于如何使用`optional`特性以及如何访问可选协议成员的指导,例如,当你不确定一个conforming类型是否实现了它们,请见:[可选协议需求]()。 +`nonobjc` -`required` +该特性用于方法、属性、下标、或构造器的声明,这些声明本是可以在Objective-C代码中表示的。使用`nonobjc`特性告诉编译器这个声明不能在Objective-C代码中使用。 -用该特性修饰一个类的指定或便利初始化器,表示该类的所有子类都必需实现该初始化器。 +可以使用`nonobjc`特性解决标有`objc`的类中桥接方法的循环问题,该特性还允许标有`objc`的类的构造器和方法进行重载(overload)。 -加了该特性的指定初始化器必需显式地实现,而便利初始化器既可显式地实现,也可以在子类实现了超类所有指定初始化器后继承而来(或者当子类使用便利初始化器重写了指定初始化器)。 +标有`nonobjc`特性的方法不能重写(override)一个标有`objc`特性的方法。然而,标有`objc`特性的方法可以重写标有`nonobjc`特性的方法。同样,标有`nonobjc`特性的方法不能满足一个需要标有`@objc`特性的方法的协议。 + +`noreturn` + +该特性用于修饰函数或方法声明,表明该函数或方法的对应类型,`T`,是`@noreturn T`。你可以用这个特性修饰函数或方法的类型,这样一来,函数或方法就不会返回到它的调用者中去。 + +对于一个没有用`noreturn`特性标记的函数或方法,你可以将它重写为用该特性标记的。相反,对于一个已经用`noreturn`特性标记的函数或方法,你则不可以将它重写为没使用该特性标记的。当你在一个comforming类型中实现一个协议方法时,该规则同样适用。 + +`NSApplicationMain` + +在类上使用该特性表示该类是应用程序委托类,使用该特性与调用`NSApplicationMain(_:_:)`函数并且把该类的名字作为委托类的名字传递给函数的效果相同。 + +如果你不想使用这个特性,可以提供一个`main.swift`文件,并且提供一个`main`函数去调用`NSApplicationMain(_:_:)`函数。比如,如果你的应用程序使用一个派生于`NSApplication`的自定义子类作为主要类,你可以调用`NSApplicationMain`函数而不是使用该特性。 + +`NSCopying` + +该特性用于修饰一个类的存储型变量属性。该特性将使属性的setter与属性值的一个副本合成,这个值由`copyWithZone(_:)`方法返回,而不是属性本身的值。该属性的类型必需遵循`NSCopying`协议。 + +`NSCopying`特性的原理与Objective-C中的`copy`特性相似。 + +`NSManaged` + +该特性用于修饰`NSManagedObject`子类中的存储型变量属性,表明属性的存储和实现由Core Data在运行时基于相关实体描述动态提供。 + +`testable` + +该特性用于`import`声明可以测试的编译模块,它能访问任何标有`internal`权限标识符的实体,这和将它声明为`public`权限标识符有同样的效果。 + +`UIApplicationMain` + +在类上使用该特性表示该类是应用程序委托类,使用该特性与调用`UIApplicationMain(_:_:)`函数并且把该类的名字作为委托类的名字传递给函数的效果相同。 + +如果你不想使用这个特性,可以提供一个`main.swift`文件,并且提供一个`main`函数去调用`UIApplicationMain(_:_:)`函数。比如,如果你的应用程序使用一个派生于`UIApplication`的自定义子类作为主要类,你可以调用`UIApplicationMain`函数而不是使用该特性。 + +`warn_unused_result` + +该特性应用于方法或函数声明,当方法或函数被调用,但其结果未被使用时,该特性会让编译器会产生警告。 + +你可以使用这个特性提供一个警告信息,这个警告信息是关于不正确地使用未变异的方法的,这个方法也有一个对应的变异方法。 + +`warn_unused_result`有下面两个可选的参数。 + +- `message`参数用来提供警告信息,并在因当方法或函数被调用,但其结果未被使用时,显示警告信息。格式如下: +
`message=message`
这里的`message`由一个字符串文字构成。 + +- `mutable_variant`参数用于提供变异方法的名称,如果未变异方法以一个可变的值被调用而且其结果并未被使用时,应该使用此变异方法。格式如下(方法名有字符串构成):
`mutable_variant=method name`
+
+比如,Swift标准库提供了变异方法`sortInPlace()`和未变异方法`sort()`集合,它们的元素生成器符合`Comparable`协议。如果你调用了`sort()`方法,而没有使用它的结果,很有可能,你打算使用变异方法`sortInPlace()`替代。
### Interface Builder使用的声明特性
@@ -137,22 +182,36 @@ Interface Builder特性是Interface Builder用来与Xcode同步的声明特性
类型特性只能用于修饰类型。然而,你也可以用`noreturn`特性去修饰函数或方法声明。
-`auto_closure`
+`convention`
-这个特性通过自动地将表达式封闭到一个无参数闭包中来延迟表达式的求值。使用该特性修饰无参的函数或方法类型,返回表达式的类型。一个如何使用`auto_closure`特性的例子,见[函数类型]()
+该特性用于函数的类型,它指出函数调用的约定。
+
+`convention`特性有下面几个可选的参数。
+
+- `swift`参数用于表明一个Swift函数引用。这是Swift中标准的函数值调用约定。
+
+- `block`参数用于表明一个Objective-C兼容的块引用。函数值表示为一个块对象的引用,这是一个`id-`兼容的Objective-C对象,对象中嵌入了调用函数。调用函数使用C的调用约定。
+
+- `c`参数用于表明一个C函数引用。函数值没有上下文,这个函数也使用C的调用约定。
+
+使用C函数调用约定的函数也可用作使用Objective-C块调用约定的函数,同时使用Objective-C块调用约定的函数也可用作使用Swift函数调用约定的函数。然而,只有非泛型的全局函数和本地函数或者不使用任何本地变量的闭包可以被用作使用C函数调用约定的函数。
`noreturn`
该特性用于修饰函数或方法的类型,表明该函数或方法不会返回到它的调用者中去。你也可以用它标记函数或方法的声明,表示函数或方法的相应类型,`T`,是`@noreturn T`。
-> 特性语法
-> *特性* → **@** [*特性名*](..\chapter3\06_Attributes.html#attribute_name) [*特性参数子句*](..\chapter3\06_Attributes.html#attribute_argument_clause) _可选_
-> *特性名* → [*标识符*](LexicalStructure.html#identifier)
-> *特性参数子句* → **(** [*平衡令牌列表*](..\chapter3\06_Attributes.html#balanced_tokens) _可选_ **)**
-> *特性(Attributes)列表* → [*特色*](..\chapter3\06_Attributes.html#attribute) [*特性(Attributes)列表*](..\chapter3\06_Attributes.html#attributes) _可选_
-> *平衡令牌列表* → [*平衡令牌*](..\chapter3\06_Attributes.html#balanced_token) [*平衡令牌列表*](..\chapter3\06_Attributes.html#balanced_tokens) _可选_
-> *平衡令牌* → **(** [*平衡令牌列表*](..\chapter3\06_Attributes.html#balanced_tokens) _可选_ **)**
-> *平衡令牌* → **[** [*平衡令牌列表*](..\chapter3\06_Attributes.html#balanced_tokens) _可选_ **]**
-> *平衡令牌* → **{** [*平衡令牌列表*](..\chapter3\06_Attributes.html#balanced_tokens) _可选_ **}**
+> 特性语法
+> *特性* → **@** [*特性名*](#attribute_name) [*特性参数子句*](#attribute_argument_clause) _可选_
+> *特性名* → [*标识符*](02_Lexical_Structure.html#identifiers)
+> *特性参数子句* → **(** [*平衡令牌列表*](#balanced_tokens) _可选_ **)**
+> *特性(Attributes)列表* → [*特色*](#attribute) [*特性(Attributes)列表*](#attributes) _可选_
+> *平衡令牌列表* → [*平衡令牌*](#balanced_token) [*平衡令牌列表*](#balanced_tokens) _可选_
+> *平衡令牌* → **(** [*平衡令牌列表*](#balanced_tokens) _可选_ **)**
+> *平衡令牌* → **[** [*平衡令牌列表*](#balanced_tokens) _可选_ **]**
+> *平衡令牌* → **{** [*平衡令牌列表*](#balanced_tokens) _可选_ **}**
> *平衡令牌* → **任意标识符, 关键字, 字面量或运算符**
> *平衡令牌* → **任意标点除了(, ), [, ], {, 或 }**
+
+
+
+
From 134c3898ee2a331fe3b156f34c6ac1a62a8c0006 Mon Sep 17 00:00:00 2001
From: shanksyang
@@ -177,15 +177,15 @@ struct AlternativeRect {
var origin = Point()
var size = Size()
var center: Point {
- get {
- let centerX = origin.x + (size.width / 2)
- let centerY = origin.y + (size.height / 2)
- return Point(x: centerX, y: centerY)
- }
- set {
- origin.x = newValue.x - (size.width / 2)
- origin.y = newValue.y - (size.height / 2)
- }
+ get {
+ let centerX = origin.x + (size.width / 2)
+ let centerY = origin.y + (size.height / 2)
+ return Point(x: centerX, y: centerY)
+ }
+ set {
+ origin.x = newValue.x - (size.width / 2)
+ origin.y = newValue.y - (size.height / 2)
+ }
}
}
```
@@ -195,26 +195,24 @@ struct AlternativeRect {
只有 getter 没有 setter 的计算属性就是*只读计算属性*。只读计算属性总是返回一个值,可以通过点运算符访问,但不能设置新的值。
-> 注意:
->
+> 注意:
> 必须使用`var`关键字定义计算属性,包括只读计算属性,因为它们的值不是固定的。`let`关键字只用来声明常量属性,表示初始化后再也无法修改的值。
-
只读计算属性的声明可以去掉`get`关键字和花括号:
```swift
struct Cuboid {
var width = 0.0, height = 0.0, depth = 0.0
var volume: Double {
- return width * height * depth
+ return width * height * depth
}
}
let fourByFiveByTwo = Cuboid(width: 4.0, height: 5.0, depth: 2.0)
-println("the volume of fourByFiveByTwo is \(fourByFiveByTwo.volume)")
+print("the volume of fourByFiveByTwo is \(fourByFiveByTwo.volume)")
// 输出 "the volume of fourByFiveByTwo is 40.0"
```
-这个例子定义了一个名为`Cuboid`的结构体,表示三维空间的立方体,包含`width`、`height`和`depth`属性,还有一个名为`volume`的只读计算属性用来返回立方体的体积。设置`volume`的值毫无意义,因为通过`width`、`height`和`depth`就能算出`volume`。然而,`Cuboid`提供一个只读计算属性来让外部用户直接获取体积是很有用的。
+这个例子定义了一个名为`Cuboid`的结构体,表示三维空间的立方体,包含`width`、`height`和`depth`属性。结构体还有一个名为`volume`的只读计算属性用来返回立方体的体积。设置`volume`的值毫无意义,因为无法确定修改`width`、`height`和`depth`三者中的哪些值来匹配新的`volume`,从而造成歧义。然而,`Cuboid`提供一个只读计算属性来让外部用户直接获取体积是很有用的。
## 属性观察器
From 44f55a7a860abee52f81980f6c5d2615daccf6ab Mon Sep 17 00:00:00 2001
From: Siyu Yang
-上面所描述的声道模型使用`AudioChannel`结构体来表示:
+上面所描述的声道模型使用`AudioChannel`结构体的实例来表示:
```swift
struct AudioChannel {
static let thresholdLevel = 10
static var maxInputLevelForAllChannels = 0
var currentLevel: Int = 0 {
- didSet {
- if currentLevel > AudioChannel.thresholdLevel {
- // 将新电平值设置为阀值
- currentLevel = AudioChannel.thresholdLevel
+ didSet {
+ if currentLevel > AudioChannel.thresholdLevel {
+ // 将新电平值设置为阀值
+ currentLevel = AudioChannel.thresholdLevel
+ }
+ if currentLevel > AudioChannel.maxInputLevelForAllChannels {
+ // 存储当前电平值作为新的最大输入电平
+ AudioChannel.maxInputLevelForAllChannels = currentLevel
+ }
}
- if currentLevel > AudioChannel.maxInputLevelForAllChannels {
- // 存储当前电平值作为新的最大输入电平
- AudioChannel.maxInputLevelForAllChannels = currentLevel
- }
- }
}
}
```
@@ -382,10 +385,10 @@ struct AudioChannel {
`AudioChannel`也定义了一个名为`currentLevel`的实例存储属性,表示当前声道现在的电平值,取值为 0 到 10。
-属性`currentLevel`包含`didSet`属性观察器来检查每次新设置后的属性值,有如下两个检查:
+属性`currentLevel`包含`didSet`属性观察器来检查每次新设置后的属性值,它有如下两个检查:
- 如果`currentLevel`的新值大于允许的阈值`thresholdLevel`,属性观察器将`currentLevel`的值限定为阈值`thresholdLevel`。
-- 如果修正后的`currentLevel`值大于任何之前任意`AudioChannel`实例中的值,属性观察器将新值保存在静态属性`maxInputLevelForAllChannels`中。
+- 如果前一个修正后的`currentLevel`值大于任何之前任意`AudioChannel`实例中的值,属性观察器将新值保存在静态类型属性`maxInputLevelForAllChannels`中。
> 注意:
> 在第一个检查过程中,`didSet`属性观察器将`currentLevel`设置成了不同的值,但这时不会再次调用属性观察器。
@@ -401,9 +404,9 @@ var rightChannel = AudioChannel()
```swift
leftChannel.currentLevel = 7
-println(leftChannel.currentLevel)
+print(leftChannel.currentLevel)
// 输出 "7"
-println(AudioChannel.maxInputLevelForAllChannels)
+print(AudioChannel.maxInputLevelForAllChannels)
// 输出 "7"
```
@@ -411,8 +414,8 @@ println(AudioChannel.maxInputLevelForAllChannels)
```swift
rightChannel.currentLevel = 11
-println(rightChannel.currentLevel)
+print(rightChannel.currentLevel)
// 输出 "10"
-println(AudioChannel.maxInputLevelForAllChannels)
+print(AudioChannel.maxInputLevelForAllChannels)
// 输出 "10"
```
From 5ff10629b56f82ebc8833d305fe5e648b2203e02 Mon Sep 17 00:00:00 2001
From: Siyu Yang