Swift基础入门(10):类型转换

文章目录
  1. 1. 类型转换
    1. 1.1. 数值型类型转换
    2. 1.2. 类型检查和向下转换
    3. 1.3. Any和AnyObject类型转换

本篇介绍Swift的基础知识:类型的检查和转换。

Title: Swift基础入门(10):类型转换
Author: Yunyao Zhang(张云尧)
E-mail: aidaizyy@gmail.com
Last Modified: 2015-07-24

类型转换

数值型类型转换

  • Int,Double,Float:
    Int16Int8不能直接相加,需要通过Int16(Int8)转换。同样,Int8UInt8Int16UInt16Int32UInt32Int64UInt64都可以互相转换。
    DoubleInt也不能相加,也需要通过Double(Int)转换,如果只需要整数部分,也可以通过Int(Double)转换。同样,Float(Int)Int(Float)Double(Float)Float(Double)都可以互相转换

  • String,Int:
    String->Int:String.toInt()函数可以把String转换成可选类型Int?,因为String中不一定能转换成Int,所以得到可选类型。
    Int->String:String(Int)函数可以把Int转换成String

类型检查和向下转换

类型检查用is操作符检查一个实例是否属于特定类型,返回true或者false
基类类型用as?或者as!操作符转换成子类类型。因为转换可能失败,所以使用as?返回可选类型的子类类型;如果确定转换一定成功,可以使用as!强制返回非可选类型的子类类型。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
class MediaItem {
var name: String
init(name: String) {
self.name = name
}
}
class Movie: MediaItem {
var director: String
init(name: String, director: String) {
self.director = director
super.init(name: name)
}
}
class Song: MediaItem {
var artist: String
init(name: String, artist: String) {
self.artist = artist
super.init(name: name)
}
}
let library = [
Movie(name: "Casablanca", director: "Michael Curtiz"),
Song(name: "Blue Suede Shoes", artist: "Elvis Presley"),
Movie(name: "Citizen Kane", director: "Orson Welles"),
Song(name: "The One And Only", artist: "Chesney Hawkes"),
Song(name: "Never Gonna Give You Up", artist: "Rick Astley")
]
// the type of "library" is inferred to be [MediaItem]
var movieCount = 0
var songCount = 0
for item in library {
if item is Movie {
++movieCount
} else if item is Song {
++songCount
}
}
println("Media library contains \(movieCount) movies and \(songCount) songs")
// prints "Media library contains 2 movies and 3 songs"
for item in library {
if let movie = item as? Movie {
println("Movie: '\(movie.name)', dir. \(movie.director)")
} else if let song = item as? Song {
println("Song: '\(song.name)', by \(song.artist)")
}
}
// Movie: 'Casablanca', dir. Michael Curtiz
// Song: 'Blue Suede Shoes', by Elvis Presley
// Movie: 'Citizen Kane', dir. Orson Welles
// Song: 'The One And Only', by Chesney Hawkes
// Song: 'Never Gonna Give You Up', by Rick Astley

Movie和类Song都是继承自类MediaItem
数组Libray自动判断类型为MediaItem,存入了两个Movie实例和三个Song实例。在for-in循环中遍历出来的都是基类类型,但它实际上存储的是子类类型。
第33-43行:item is Movieitem is Song判断item实际存储的值是不是子类类型,是的话在相应数量的记录上加1,最后输出各子类类型的数组元素的个数。
第45-56行:item as? Movieitem as? Songitem强制转换成子类类型,如果实际存储的不相符返回nil,实际存储的相符返回相应的子类类型,并打印相应信息。

Any和AnyObject类型转换

  • Any:任意类型,包括方法类型。
  • AnyObject:任意class类型。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    let someObjects: [AnyObject] = [
    Movie(name: "2001: A Space Odyssey", director: "Stanley Kubrick"),
    Movie(name: "Moon", director: "Duncan Jones"),
    Movie(name: "Alien", director: "Ridley Scott")
    ]
    var things = [Any]()
    things.append(0)
    things.append(0.0)
    things.append("hello")

someObject是一个很多class类型组成的混合class类型数组,所以用AnyObject
things是一个很多类型组成的混合类型数组,所以用Any
它们的访问都可以通过遍历,然后使用is判断或者as转换。

switchcase语句中,使用as而不是as?。因为case语句中类型的检查和转换总是安全的。

转载请注明原作者和出处。

如果觉得这篇文章对您有帮助或启发,请随意打赏~