类型转换

266 阅读3分钟
  1. 类型判断操作符
    1. ==,!=判断俩个值类型是否相等
    2. ===,!==判断两个引用是否是一个内存地址
    3. is判断某个对象是否是某个类型
class MediaItem {
    var name: String
    init(name: String) {
        self.name = name
    }
}

class Movie: MediaItem {
    var director: String
    init(director: String, name:String) {
        self.director = director
        super.init(name: name)
    }
}

class Song: MediaItem {
    var artist: String
    init(artist: String, name: String) {
        self.artist = artist
        super.init(name: name)
    }
}

//library被推断出来存储的类型是MediaItem类型,所以遍历时候取出来的每一个item类型默认都是MediaItem类型
let library = [
    Movie(director: "1", name: "1"),
    Song(artist: "2", name: "2"),
    Song(artist: "3", name: "3"),
    Movie(director: "4", name: "4"),
    Song(artist: "5", name: "5"),
]

var movieCount = 0, songCount = 0
for  item in library {
    //item是MediaItem类型
    if item is Movie {
        movieCount += 1
    }else if item is Song{
        songCount += 1
    }
}
print("moveCount = \(movieCount)   songCount = \(songCount)")
  1. 向下转型
    1. 当不确定转型是否会是确定的子类类型时候要用as?
    2. 当确定转型会是确定的子类类型时候要用as!
    3. 向上转型总是会成功,没有意义的!没有关联的对象转型总是会失败,也是没意义的。所以只是存在向下转型。转成更加确定的类型。
class MediaItem {
    var name: String
    init(name: String) {
        self.name = name
    }
}

class Movie: MediaItem {
    var director: String
    init(director: String, name:String) {
        self.director = director
        super.init(name: name)
    }
}

class Song: MediaItem {
    var artist: String
    init(artist: String, name: String) {
        self.artist = artist
        super.init(name: name)
    }
}

//library被推断出来存储的类型是MediaItem类型,所以遍历时候取出来的每一个item类型默认都是MediaItem类型
let library = [
    Movie(director: "1", name: "1"),
    Song(artist: "2", name: "2"),
    Song(artist: "3", name: "3"),
    Movie(director: "4", name: "4"),
    Song(artist: "5", name: "5"),
]

var movieCount = 0
var songCount = 0
for item in library {
    //item默认是MediaItem类型
    if let _ = item as? Movie{
        movieCount += 1
    } else if let _ = item as? Song{
        songCount += 1
    }
}

print("movieCount = \(movieCount)   songCount = \(songCount)")
  1. Any与AnyObject区别

    1. AnyObject是Any的子类
    2. AnyObject只是表示对象类型
    3. Any可以表示所有任意类型,包括值,对象,可选,函数类型等。
    4. 碰见Any类型时候可能编译器给出警报,这时候可以用 as Any来消除警报.
  2. as,as?,as!

    1. 如果涉及到向上转型,值类型,case匹配对象,消除可选类型使用时候的警告用as。
    2. 如果涉及到向下转型,可能会失败用as?。
    3. 如果涉及到向下转型,一定成功用as!。
class Animal {}
class Dog: Animal {}

/*** as使用场景 ***/
//1. as值类型
var a = 4
let b = a as Int

//2. as向上转型
var c = Dog()
let d = c as Animal

//3. switch,case匹配对象
switch d {
case  _ as Dog :
    break
default:
    break
}

//4. 消除Any类型警报
var g: Int?
print(g as Any)

var h: Int? = 5
print(h!)
print(h as Any)

/*** as?使用场景 ***/
//1. 向下转型可能会失败
var e = d as? Dog

/*** as!使用场景 ***/
//1. 向下转型确保一定成功
var f = d as! Dog
  1. 由于使用了可选类型可能导致警报,这时候如果确定可选类型一定有值。那么可以用!强制解包,也可以用 a as Any来解决警报。
    这时候如果可能是缺省值那么就只能用a as Any来解决警报。