19,type casting ,for 3.0.1

This commit is contained in:
shanks
2016-11-13 15:42:51 +08:00
parent 4f24490fe4
commit dc3b19aa6f

View File

@ -1,4 +1,4 @@
# 类型转换Type Casting
# 类型转换
-----------------
> 1.0
@ -12,13 +12,14 @@
> 校对:[shanks](http://codebuild.me)2015-11-01
>
> 2.2
> 翻译+校对:[SketchK](https://github.com/SketchK) 2016-05-16
> 翻译+校对:[SketchK](https://github.com/SketchK) 2016-05-16
> 3.0.1shanks2016-11-13
本页包含内容:
- [定义一个类层次作为例子](#defining_a_class_hierarchy_for_type_casting)
- [检查类型](#checking_type)
- [向下转型Downcasting](#downcasting)
- [向下转型](#downcasting)
- [`Any` 和 `AnyObject` 的类型转换](#type_casting_for_any_and_anyobject)
@ -80,7 +81,7 @@ let library = [
在幕后 `library` 里存储的媒体项依然是 `Movie``Song` 类型的。但是,若你迭代它,依次取出的实例会是 `MediaItem` 类型的,而不是 `Movie``Song` 类型。为了让它们作为原本的类型工作,你需要检查它们的类型或者向下转换它们到其它类型,就像下面描述的一样。
<a name="checking_type"></a>
## 检查类型Checking Type
## 检查类型
用类型检查操作符(`is`)来检查一个实例是否属于特定子类型。若实例属于那个子类型,类型检查操作符返回 `true`,否则返回 `false`
@ -109,13 +110,13 @@ print("Media library contains \(movieCount) movies and \(songCount) songs")
`true`,否则返回 `false`。同样的,`item is Song` 检查 `item` 是否为 `Song` 类型的实例。在循环结束后,`movieCount``songCount` 的值就是被找到的属于各自类型的实例的数量。
<a name="downcasting"></a>
## 向下转型Downcasting
## 向下转型
某类型的一个常量或变量可能在幕后实际上属于一个子类。当确定是这种情况时,你可以尝试向下转到它的子类型,用类型转换操作符(`as?``as!`)。
某类型的一个常量或变量可能在幕后实际上属于一个子类。当确定是这种情况时,你可以尝试向下转到它的子类型,用*类型转换操作符*`as?``as!`)。
因为向下转型可能会失败,类型转型操作符带有两种不同形式。条件形式conditional form`as?` 返回一个你试图向下转成的类型的可选值optional value。强制形式 `as!` 把试图向下转型和强制解包(force-unwraps转换结果结合为一个操作。
因为向下转型可能会失败,类型转型操作符带有两种不同形式。条件形式`as?` 返回一个你试图向下转成的类型的可选值。强制形式 `as!` 把试图向下转型和强制解包(转换结果结合为一个操作。
当你不确定向下转型可以成功时,用类型转换的条件形式(`as?`)。条件形式的类型转换总是返回一个可选值optional value,并且若下转是不可能的,可选值将是 `nil`。这使你能够检查向下转型是否成功。
当你不确定向下转型可以成功时,用类型转换的条件形式(`as?`)。条件形式的类型转换总是返回一个可选值,并且若下转是不可能的,可选值将是 `nil`。这使你能够检查向下转型是否成功。
只有你可以确定向下转型一定会成功时,才使用强制形式(`as!`)。当你试图向下转型为一个不正确的类型时,强制形式的类型转换会触发一个运行时错误。
@ -158,55 +159,10 @@ for item in library {
Swift 为不确定类型提供了两种特殊的类型别名:
* `AnyObject` 可以表示任何类类型的实例。
* `Any` 可以表示任何类型,包括函数类型。
* `AnyObject` 可以表示任何类类型的实例。
> 注意
> 只有当你确实需要它们的行为和功能时才使用 `Any` 和 `AnyObject`。在你的代码里使用你期望的明确类型总是更好的。
<a name="anyobject"></a>
### `AnyObject` 类型
当我们使用 Cocoa APIs 时,我们会接收到一个 `[AnyObject]` 类型的数组或者说“一个任意类型对象的数组”。Objective-C现在支持明确的数组类型但早期版本的Objective-C并没有这个功能。不管怎样你都可以确信API提供的信息能够正确的表明数组中的元素类型。
在这些情况下,你可以使用强制形式的类型转换(`as!`)来下转数组中的每一项到比 `AnyObject` 更明确的类型不需要可选解包optional unwrapping
下面的示例定义了一个 `[AnyObject]` 类型的数组并填入三个 `Movie` 类型的实例:
```swift
let someObjects: [AnyObject] = [
Movie(name: "2001: A Space Odyssey", director: "Stanley Kubrick"),
Movie(name: "Moon", director: "Duncan Jones"),
Movie(name: "Alien", director: "Ridley Scott")
]
```
因为知道这个数组只包含 `Movie` 实例,你可以直接用(`as!`)下转并解包到非可选的 `Movie` 类型:
```swift
for object in someObjects {
let movie = object as! Movie
print("Movie: '\(movie.name)', dir. \(movie.director)")
}
// Movie: '2001: A Space Odyssey', dir. Stanley Kubrick
// Movie: 'Moon', dir. Duncan Jones
// Movie: 'Alien', dir. Ridley Scott
```
为了变为一个更简短的形式,下转 `someObjects` 数组为 `[Movie]` 类型而不是下转数组中的每一项:
```swift
for movie in someObjects as! [Movie] {
print("Movie: '\(movie.name)', dir. \(movie.director)")
}
// Movie: '2001: A Space Odyssey', dir. Stanley Kubrick
// Movie: 'Moon', dir. Duncan Jones
// Movie: 'Alien', dir. Ridley Scott
```
<a name="any"></a>
### `Any` 类型
只有当你确实需要它们的行为和功能时才使用 `Any``AnyObject`。在你的代码里使用你期望的明确类型总是更好的。
这里有个示例,使用 `Any` 类型来和混合的不同类型一起工作,包括函数类型和非类类型。它创建了一个可以存储 `Any` 类型的数组 `things`
@ -262,3 +218,12 @@ for thing in things {
// a movie called 'Ghostbusters', dir. Ivan Reitman
// Hello, Michael
```
> 注意
> `Any`类型可以表示所有类型的值包括可选类型。Swift 会在你用`Any`类型来表示一个可选值的时候,给你一个警告。如果你确实想使用`Any`类型来承载可选值,你可以使用`as`操作符显示转换为`Any`,如下所示:
>
```swift
let optionalNumber: Int? = 3
things.append(optionalNumber) // 警告
things.append(optionalNumber as Any) // 没有警告
```