Merge branch 'gh-pages' of https://github.com/numbbbbb/the-swift-programming-language-in-chinese into gh-pages
This commit is contained in:
@ -335,7 +335,7 @@ Swift 的字典使用`Dictionary<KeyType, ValueType>`定义,其中`KeyType`是
|
||||
var namesOfIntegers = Dictionary<Int, String>()
|
||||
// namesOfIntegers 是一个空的 Dictionary<Int, String>
|
||||
|
||||
这个例子创建了一个`Int, String`类型的空字典来储存英语对整数的命名。他的键是`Int`型,值是`String`型。
|
||||
这个例子创建了一个`Int, String`类型的空字典来储存英语对整数的命名。它的键是`Int`型,值是`String`型。
|
||||
|
||||
如果上下文已经提供了信息类型,我们可以使用空字典字面语句来创建一个空字典,记作`[:]`(中括号中放一个冒号):
|
||||
|
||||
|
||||
@ -14,17 +14,17 @@
|
||||
- [通过可选链调用方法](#calling_methods_through_optional_chaining)
|
||||
- [使用可选链调用子脚本](#calling_subscripts_through_optional_chaining)
|
||||
- [连接多层链接](#linking_multiple_levels_of_chaining)
|
||||
- [链接自判断返回值的方法](#chaining_on_methods_with_optional_return_values)
|
||||
- [链接可选返回值的方法](#chaining_on_methods_with_optional_return_values)
|
||||
|
||||
可选链(Optional Chaining)是一种可以请求和调用属性、方法及子脚本的过程,它的自判断性体现于请求或调用的目标当前可能为空(`nil`)。如果自判断的目标有值,那么调用就会成功;相反,如果选择的目标为空(`nil`),则这种调用将返回空(`nil`)。多次请求或调用可以被链接在一起形成一个链,如果任何一个节点为空(`nil`)将导致整个链失效。
|
||||
可选链(Optional Chaining)是一种可以请求和调用属性、方法及子脚本的过程,它的可选性体现于请求或调用的目标当前可能为空(`nil`)。如果可选的目标有值,那么调用就会成功;相反,如果选择的目标为空(`nil`),则这种调用将返回空(`nil`)。多次请求或调用可以被链接在一起形成一个链,如果任何一个节点为空(`nil`)将导致整个链失效。
|
||||
|
||||
> 注意:
|
||||
Swift 的自判断链和 Objective-C 中的消息为空有些相像,但是 Swift 可以使用在任意类型中,并且失败与否可以被检测到。
|
||||
Swift 的可选链和 Objective-C 中的消息为空有些相像,但是 Swift 可以使用在任意类型中,并且失败与否可以被检测到。
|
||||
|
||||
<a name="optional_chaining_as_an_alternative_to_forced_unwrapping"></a>
|
||||
## 可选链可替代强制解析
|
||||
|
||||
通过在想调用的属性、方法、或子脚本的可选值(`optional value`)(非空)后面放一个问号,可以定义一个可选链。这一点很像在可选值后面放一个声明符号来强制拆得其封包内的值。他们的主要的区别在于当可选值为空时可选链即刻失败,然而一般的强制解析将会引发运行时错误。
|
||||
通过在想调用的属性、方法、或子脚本的可选值(`optional value`)(非空)后面放一个问号,可以定义一个可选链。这一点很像在可选值后面放一个叹号来强制拆得其封包内的值。他们的主要的区别在于当可选值为空时可选链即刻失败,然而一般的强制解析将会引发运行时错误。
|
||||
|
||||
为了反映可选链可以调用空(`nil`),不论你调用的属性、方法、子脚本等返回的值是不是可选值,它的返回结果都是一个可选值。你可以利用这个返回值来检测你的可选链是否调用成功,有返回值即成功,返回nil则失败。
|
||||
|
||||
@ -42,9 +42,9 @@ Swift 的自判断链和 Objective-C 中的消息为空有些相像,但是 Swi
|
||||
var numberOfRooms = 1
|
||||
}
|
||||
|
||||
`Residence`具有一个`Int`类型的`numberOfRooms`,其值为 1。`Person`具有一个自判断`residence`属性,它的类型是`Residence?`。
|
||||
`Residence`具有一个`Int`类型的`numberOfRooms`,其值为 1。`Person`具有一个可选`residence`属性,它的类型是`Residence?`。
|
||||
|
||||
如果你创建一个新的`Person`实例,它的`residence`属性由于是被定义为自判断型的,此属性将默认初始化为空:
|
||||
如果你创建一个新的`Person`实例,它的`residence`属性由于是被定义为可选型的,此属性将默认初始化为空:
|
||||
|
||||
let john = Person()
|
||||
|
||||
@ -64,11 +64,11 @@ Swift 的自判断链和 Objective-C 中的消息为空有些相像,但是 Swi
|
||||
// 打印 "Unable to retrieve the number of rooms.
|
||||
|
||||
|
||||
这告诉 Swift 来链接自判断`residence?`属性,如果`residence`存在则取回`numberOfRooms`的值。
|
||||
这告诉 Swift 来链接可选`residence?`属性,如果`residence`存在则取回`numberOfRooms`的值。
|
||||
|
||||
因为这种尝试获得`numberOfRooms`的操作有可能失败,可选链会返回`Int?`类型值,或者称作“自判断`Int`”。当`residence`是空的时候(上例),选择`Int`将会为空,因此会出先无法访问`numberOfRooms`的情况。
|
||||
因为这种尝试获得`numberOfRooms`的操作有可能失败,可选链会返回`Int?`类型值,或者称作“可选`Int`”。当`residence`是空的时候(上例),选择`Int`将会为空,因此会出先无法访问`numberOfRooms`的情况。
|
||||
|
||||
要注意的是,即使numberOfRooms是非自判断`Int`(`Int?`)时这一点也成立。只要是通过可选链的请求就意味着最后`numberOfRooms`总是返回一个`Int?`而不是`Int`。
|
||||
要注意的是,即使numberOfRooms是非可选`Int`(`Int?`)时这一点也成立。只要是通过可选链的请求就意味着最后`numberOfRooms`总是返回一个`Int?`而不是`Int`。
|
||||
|
||||
你可以自己定义一个`Residence`实例给`john.residence`,这样它就不再为空了:
|
||||
|
||||
@ -118,7 +118,7 @@ Swift 的自判断链和 Objective-C 中的消息为空有些相像,但是 Swi
|
||||
|
||||
`Residence`中也提供了一个`printNumberOfRooms`的方法,即简单的打印房间个数。
|
||||
|
||||
最后,`Residence`定义了一个自判断属性叫`address`(`address?`)。`Address`类的属性将在后面定义。
|
||||
最后,`Residence`定义了一个可选属性叫`address`(`address?`)。`Address`类的属性将在后面定义。
|
||||
用于`rooms`数组的`Room`类是一个很简单的类,它只有一个`name`属性和一个设定`room`名的初始化器。
|
||||
|
||||
class Room {
|
||||
@ -127,7 +127,7 @@ Swift 的自判断链和 Objective-C 中的消息为空有些相像,但是 Swi
|
||||
}
|
||||
|
||||
|
||||
这个模型中的最终类叫做`Address`。它有三个自判断属性他们额类型是`String?`。前面两个自判断属性`buildingName`和 `buildingNumber`作为地址的一部分,是定义某个建筑物的两种方式。第三个属性`street`,用于命名地址的街道名:
|
||||
这个模型中的最终类叫做`Address`。它有三个类型是`String?`的可选属性。前面两个可选属性`buildingName`和 `buildingNumber`作为地址的一部分,是定义某个建筑物的两种方式。第三个属性`street`,用于命名地址的街道名:
|
||||
|
||||
class Address {
|
||||
var buildingName: String?
|
||||
@ -176,7 +176,7 @@ Swift 的自判断链和 Objective-C 中的消息为空有些相像,但是 Swi
|
||||
|
||||
这个方法没有返回值。但是,没有返回值类型的函数和方法有一个隐式的返回值类型`Void`(参见Function Without Return Values)。
|
||||
|
||||
如果你利用可选链调用此方法,这个方法的返回值类型将是`Void?`,而不是`Void`,因为当通过可选链调用方法时返回值总是可选类型(optional type)。,即使是这个方法本是没有定义返回值,你也可以使用`if`语句来检查是否能成功调用`printNumberOfRooms`方法:如果方法通过可选链调用成功,`printNumberOfRooms`的隐式返回值将会是`Void`,如果没有成功,将返回`nil`:
|
||||
如果你利用可选链调用此方法,这个方法的返回值类型将是`Void?`,而不是`Void`,因为当通过可选链调用方法时返回值总是可选类型(optional type)。即使这个方法本身没有定义返回值,你也可以使用`if`语句来检查是否能成功调用`printNumberOfRooms`方法:如果方法通过可选链调用成功,`printNumberOfRooms`的隐式返回值将会是`Void`,如果没有成功,将返回`nil`:
|
||||
|
||||
if john.residence?.printNumberOfRooms() {
|
||||
println("It was possible to print the number of rooms.")
|
||||
@ -191,7 +191,7 @@ Swift 的自判断链和 Objective-C 中的消息为空有些相像,但是 Swi
|
||||
你可以使用可选链来尝试从子脚本获取值并检查子脚本的调用是否成功,然而,你不能通过可选链来设置子代码。
|
||||
|
||||
> 注意:
|
||||
当你使用可选链来获取子脚本的时候,你应该将问号放在子脚本括号的前面而不是后面。可选链的问号一般直接跟在自判断表达语句的后面。
|
||||
当你使用可选链来获取子脚本的时候,你应该将问号放在子脚本括号的前面而不是后面。可选链的问号一般直接跟在表达语句的后面。
|
||||
|
||||
下面这个例子用在`Residence`类中定义的子脚本来获取`john.residence`数组中第一个房间的名字。因为`john.residence`现在是`nil`,子脚本的调用失败了。
|
||||
|
||||
@ -225,7 +225,7 @@ Swift 的自判断链和 Objective-C 中的消息为空有些相像,但是 Swi
|
||||
也就是说:
|
||||
|
||||
如果你试图获得的类型不是可选类型,由于使用了可选链它将变成可选类型。
|
||||
如果你试图获得的类型已经是可选类型,由于可选链它也不会提高自判断性。
|
||||
如果你试图获得的类型已经是可选类型,由于可选链它也不会提高可选性。
|
||||
|
||||
因此:
|
||||
|
||||
@ -259,12 +259,12 @@ Swift 的自判断链和 Objective-C 中的消息为空有些相像,但是 Swi
|
||||
}
|
||||
// 打印 "John's street name is Laurel Street."。
|
||||
|
||||
值得注意的是,“`!`”符的在定义`address`实例时的使用(`john.residence.address`)。`john.residence`属性是一个可选类型,因此你需要在它获取`address`属性之前使用`!`解析以获得它的实际值。
|
||||
值得注意的是,“`!`”符号在给`john.residence.address`分配`address`实例时的使用。`john.residence`属性是一个可选类型,因此你需要在它获取`address`属性之前使用`!`解析以获得它的实际值。
|
||||
|
||||
<a name="chaining_on_methods_with_optional_return_values"></a>
|
||||
##链接自判断返回值的方法
|
||||
##链接可选返回值的方法
|
||||
|
||||
前面的例子解释了如何通过可选链来获得可选类型属性值。你也可以通过调用返回可选类型值的方法并按需链接方法的返回值。
|
||||
前面的例子解释了如何通过可选链来获得可选类型属性值。你也可以通过可选链调用一个返回可选类型值的方法并按需链接该方法的返回值。
|
||||
|
||||
下面的例子通过可选链调用了`Address`类中的`buildingIdentifier` 方法。这个方法的返回值类型是`String?`。如上所述,这个方法在可选链调用后最终的返回值类型依然是`String?`:
|
||||
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
> 校对:happyming
|
||||
|
||||
# 类型检查(Type Casting)
|
||||
# 类型转换(Type Casting)
|
||||
-----------------
|
||||
|
||||
本页包含内容:
|
||||
@ -10,14 +10,14 @@
|
||||
- [定义一个类层次作为例子](#defining_a_class_hierarchy_for_type_casting)
|
||||
- [检查类型](#checking_type)
|
||||
- [向下转型(Downcasting)](#downcasting)
|
||||
- [`Any`和`AnyObject`的类型检查](#type_casting_for_any_and_anyobject)
|
||||
- [`Any`和`AnyObject`的类型转换](#type_casting_for_any_and_anyobject)
|
||||
|
||||
|
||||
_类型检查_是一种检查类实例的方式,并且或者也是让实例作为它的父类或者子类的一种方式。
|
||||
|
||||
类型检查在 Swift 中使用`is` 和 `as`操作符实现。这两个操作符提供了一种简单达意的方式去检查值的类型或者转换它的类型。
|
||||
|
||||
你也可以用来检查一个类是否实现了某个协议,就像在 [Protocols Checking for Protocol Conformance](Protocols.html#//apple_ref/doc/uid/TP40014097-CH25-XID_363)部分讲述的一样。
|
||||
你也可以用来检查一个类是否实现了某个协议,就像在 [Checking for Protocol Conformance](Protocols.html#//apple_ref/doc/uid/TP40014097-CH25-XID_363)部分讲述的一样。
|
||||
|
||||
<a name="defining_a_class_hierarchy_for_type_casting"></a>
|
||||
## 定义一个类层次作为例子
|
||||
@ -68,7 +68,7 @@
|
||||
<a name="checking_type"></a>
|
||||
## 检查类型
|
||||
|
||||
用类型检查操作符(`is`)来检查一个实例是否属于特定子类型。类型检查操作符返回 `true` 若实例属于那个子类型,若不属于返回 `false` 。
|
||||
用类型检查操作符(`is`)来检查一个实例是否属于特定子类型。若实例属于那个子类型,类型检查操作符返回 `true` ,否则返回 `false` 。
|
||||
|
||||
下面的例子定义了两个变量,`movieCount` 和 `songCount`,用来计算数组`library` 中 `Movie` 和 `Song` 类型的实例数量。
|
||||
|
||||
@ -96,17 +96,17 @@
|
||||
<a name="downcasting"></a>
|
||||
## 向下转型(Downcasting)
|
||||
|
||||
某类型的一个常量或变量可能在幕后实际上属于一个子类。你可以相信,上面就是这种情况。你可以尝试向下转到它的子类型,用类型检查操作符(`as`)
|
||||
某类型的一个常量或变量可能在幕后实际上属于一个子类。你可以相信,上面就是这种情况。你可以尝试向下转到它的子类型,用类型转换操作符(`as`)
|
||||
|
||||
因为向下转型可能会失败,类型检查操作符带有两种不同形式。可选形式( optional form) `as?` 返回一个你试图下转成的类型的可选值(optional value)。强制形式 `as` 把试图向下转型和强制解包(force-unwraps)结果作为一个混合动作。
|
||||
因为向下转型可能会失败,类型转型操作符带有两种不同形式。可选形式( optional form) `as?` 返回一个你试图下转成的类型的可选值(optional value)。强制形式 `as` 把试图向下转型和强制解包(force-unwraps)结果作为一个混合动作。
|
||||
|
||||
当你不确定下转可以成功时,用类型检查的可选形式(`as?`)。可选形式的类型检查总是返回一个可选值(optional value),并且若下转是不可能的,可选值将是 `nil` 。这使你能够检查下转是否成功。
|
||||
当你不确定向下转型可以成功时,用类型转换的可选形式(`as?`)。可选形式的类型转换总是返回一个可选值(optional value),并且若下转是不可能的,可选值将是 `nil` 。这使你能够检查向下转型是否成功。
|
||||
|
||||
只有你可以确定下转一定会成功时,才使用强制形式。当你试图下转为一个不正确的类型时,强制形式的类型检查会触发一个运行时错误。
|
||||
只有你可以确定向下转型一定会成功时,才使用强制形式。当你试图向下转型为一个不正确的类型时,强制形式的类型转换会触发一个运行时错误。
|
||||
|
||||
下面的例子,迭代了`library`里的每一个 `MediaItem` ,并打印出适当的描述。要这样做,`item`需要真正作为`Movie` 或 `Song`的类型来使用。不仅仅是作为 `MediaItem`。为了能够使用`Movie` 或 `Song`的 `director` 或 `artist`属性,这是必要的。
|
||||
|
||||
在这个示例中,数组中的每一个`item`可能是 `Movie` 或 `Song`。 事前你不知道每个`item`的真实类型,所以这里使用可选形式的类型检查 (`as?`)去检查循环里的每次下转。
|
||||
在这个示例中,数组中的每一个`item`可能是 `Movie` 或 `Song`。 事前你不知道每个`item`的真实类型,所以这里使用可选形式的类型转换 (`as?`)去检查循环里的每次下转。
|
||||
|
||||
for item in library {
|
||||
if let movie = item as? Movie {
|
||||
@ -126,19 +126,19 @@
|
||||
类型的实例,它可能是一个`Movie`;同样,它可能是一个 `Song`,或者仅仅是基类
|
||||
`MediaItem`。因为不确定,`as?`形式在试图下转时将返还一个可选值。 `item as Movie` 的返回值是`Movie?`类型或 “optional `Movie`”。
|
||||
|
||||
当下转为 `Movie` 应用在两个 `Song`
|
||||
当向下转型为 `Movie` 应用在两个 `Song`
|
||||
实例时将会失败。为了处理这种情况,上面的例子使用了可选绑定(optional binding)来检查可选 `Movie`真的包含一个值(这个是为了判断下转是否成功。)可选绑定是这样写的“`if let movie = item as? Movie`”,可以这样解读:
|
||||
|
||||
“尝试将 `item` 转为 `Movie`类型。若成功,设置一个新的临时常量 `movie` 来存储返回的可选`Movie`”
|
||||
|
||||
若下转成功,然后`movie`的属性将用于打印一个`Movie`实例的描述,包括它的导演的名字`director`。当`Song`被找到时,一个相近的原理被用来检测 `Song` 实例和打印它的描述。
|
||||
若向下转型成功,然后`movie`的属性将用于打印一个`Movie`实例的描述,包括它的导演的名字`director`。当`Song`被找到时,一个相近的原理被用来检测 `Song` 实例和打印它的描述。
|
||||
|
||||
> 注意:
|
||||
>
|
||||
转换没有真的改变实例或它的值。潜在的根本的实例保持不变;只是简单地把它作为它被转换成的类来使用。
|
||||
|
||||
<a name="type_casting_for_any_and_anyobject"></a>
|
||||
## `Any`和`AnyObject`的类型检查
|
||||
## `Any`和`AnyObject`的类型转换
|
||||
|
||||
Swift为不确定类型提供了两种特殊类型别名:
|
||||
|
||||
@ -155,7 +155,7 @@
|
||||
当需要在工作中使用 Cocoa
|
||||
APIs,它一般接收一个`AnyObject[]`类型的数组,或者说“一个任何对象类型的数组”。这是因为 Objective-C 没有明确的类型化数组。但是,你常常可以确定包含在仅从你知道的 API 信息提供的这样一个数组中的对象的类型。
|
||||
|
||||
在这些情况下,你可以使用强制形式的类型检查(`as`)来下转在数组中的每一项到比 `AnyObject` 更明确的类型,不需要可选解析(optional unwrapping)。
|
||||
在这些情况下,你可以使用强制形式的类型转换(`as`)来下转在数组中的每一项到比 `AnyObject` 更明确的类型,不需要可选解析(optional unwrapping)。
|
||||
|
||||
下面的示例定义了一个 `AnyObject[]` 类型的数组并填入三个`Movie`类型的实例:
|
||||
|
||||
@ -236,4 +236,4 @@
|
||||
|
||||
> 注意:
|
||||
>
|
||||
在一个switch语句的case中使用强制形式的类型检查操作符(as, 而不是 as?)来检查和转换到一个明确的类型。在 switch case 语句的内容中这种检查总是安全的。
|
||||
在一个switch语句的case中使用强制形式的类型转换操作符(as, 而不是 as?)来检查和转换到一个明确的类型。在 switch case 语句的内容中这种检查总是安全的。
|
||||
|
||||
Reference in New Issue
Block a user