美文网首页
19.内嵌类型 Nested Type Swift官方文档——版

19.内嵌类型 Nested Type Swift官方文档——版

作者: KevinFromChina | 来源:发表于2018-03-28 21:32 被阅读0次
    //: Playground - noun: a place where people can play
    
    import UIKit
    
    // # 为类型转换定义类层次
    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")
    ] // 注意:library的类型被推断为[MediaItem].而事实上,library存储的项目在后台依旧是各自的类型的实例.但是遍历这个数组取出的将会是MediaItem类型
    
    // # 类型检查
    var movieCount = 0
    var songCount = 0
    for item in library {
        if item is Movie {
            movieCount += 1
        } else if item is Song {
            songCount += 1
        }
    }
    print("Media library contains \(movieCount) movies and \(songCount) songs")
    library[0] is MediaItem
    // another example
    var controller = UITableViewController()
    controller is CustomDebugStringConvertible
    
    // # 向下类型转换
    // as 用于消除二义性
    let num1 = 42 as CGFloat
    let num2 = 42 as Int
    let num3 = 42 as Double
    class Animal {}
    class Cat: Animal {}
    let cat = Cat()
    let animal = cat as Animal // as is used to make an instance become its father class instance--this will never fail.
    let kitty = animal as! Cat // as! is used to downcast a father instance--this can fail.
    
    // as & protocol
    protocol Facial {
        var faceSize: Double { get set }
    }
    class Human: Facial {
        var faceSize: Double = 1
    }
    class Dog: Facial {
        var faceSize: Double = 0.5
    }
    let creatureOne: Facial = Human()
    let humanOne = creatureOne as! Human
    let creatureTwo = humanOne as Facial
    
    // as?返回可选项,as!强制转换
    // 情况1: 左操作数非可选,存疑在于其能不能进行转换
    for item in library {
        if let movie = item as? Movie {
            print("Movie: '\(movie.name)', director \(movie.director)")
        } else if let song = item as? Song {
            print("Song: '\(song.name)', by \(song.artist)")
        }
    }
    // 情况2: 左操作数是可选,存疑在于存不存在以及存在时能不能转换
    var itemMaybe: MediaItem? = Movie(name: "I Love You", director: "Berg")
    let songMaybe = itemMaybe as? Song
    let movieMaybe = itemMaybe as? Movie
    let movieMaybeTwo = itemMaybe as! Movie
    
    // 注意:也可以将类转化为基类,但是基类仍然保留了子类数据
    let movie = Movie(name: "Casablanca", director: "Michael Curtiz")
    let ss = movie as MediaItem
    ss as? Movie
    
    // # Any和AnyObject的类型转换
    // AnyObject 可以表示任何类类型实例
    // Any 可以表示任何类型,包括函数类型
    var things = [Any]()
    things.append(0)
    things.append(0.0)
    things.append(42)
    things.append(3.14159)
    things.append("hello")
    things.append((3.0, 5.0))
    things.append(Movie(name: "Ghostbusters", director: "Ivan Reitman"))
    things.append({ (name: String) -> String in "Hello, \(name)" })
    // trick: is 和 as 灵活使用
    for thing in things {
        switch thing {
        case 0 as Int:
            print("zero as an Int")
        case 0 as Double:
            print("zero as a Double")
        case let someInt as Int:
            print("an integer value of \(someInt)")
        case let someDouble as Double where someDouble > 0:
            print("a positive double value of \(someDouble)")
        case is Double:
            print("some other double value that I don't want to print")
        case let someString as String:
            print("a string value of \"\(someString)\"")
        case let (x, y) as (Double, Double):
            print("an (x, y) point at \(x), \(y)")
        case let movie as Movie:
            print("a movie called \(movie.name), dir. \(movie.director)")
        case let stringConverter as (String) -> String:
            print(stringConverter("Michael"))
        default:
            print("something else")
        }
    }
    let optionalNumber: Int? = 3
    things.append(optionalNumber)        // Warning
    things.append(optionalNumber as Any) // No warning
    
    
    // 返回不同的类型
    func function() -> MediaItem {
        return Movie(name: "Whatever", director: "Kevin")
    }
    let some = function()
    some.name
    let dd = some as! Movie
    dd.director
    

    相关文章

      网友评论

          本文标题:19.内嵌类型 Nested Type Swift官方文档——版

          本文链接:https://www.haomeiwen.com/subject/dnzucftx.html