19:swift-类型转换

 

 

正文

 

/* 类型转换
 
 1:类型转换
    类型转换可以判断实例的类型,也可以将该实例在其所在的类层次中视为其父类或子类的实例。
    Swift 中类型转换的实现为 is 和 as 操作符。
    这两个操作符使用了一种简单传神的方式来检查一个值的类型或将某个值转换为另一种类型
    你还可以使用类型转换来检查类型是否遵循某个协议。
 
 4: Any类型
     类、结构体或者枚举;
     元类型,比如 Int.self ;
     带有任意类型元素的元组;
     闭包或者函数类型
 
   AnyObject类型
    所有类都隐式遵循AnyObject协议,这也限制了AnyObject是只适用于Class类型的原因。
 */
import UIKit

class TypeConvert19VC: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white
        self.title = "19:类型转换"

        /* 1:创建数组
         如果你遍历这个数组的内容,你取出的项目将会是 MediaItem 类型而非 Movie 或 Song 类型。为了使用他们原生的类型,你需要检查他们的类型或将他们向下转换为不同的类型,
         */
        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")
        ]
        
        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")
        
        /* 2:向下转换
             某个类类型的常量或变量可能实际上在后台引用自一个子类的实例。
             当你遇到这种情况时你可以尝试使用类型转换操作符( as? 或 as! )将它向下类型转换至其子类类型。

             由于向下类型转换能失败,类型转换操作符就有了两个不同形式。
             条件形式, as? ,返回了一个你将要向下类型转换的值的可选项。
             强制形式, as! ,则将向下类型转换和强制展开结合为一个步骤。
         
             类型转换实际上不会改变实例及修改其值。实例不会改变;它只是将它当做要转换的类型来访问。
         */
        for item in library {
            if let movie = item as? Movie {
                print("Movie: '\(movie.name)', dir. \(movie.director)")
            } else if let song = item as? Song {
                print("Song: '\(song.name)', by \(song.artist)")
            }
        }
        
        /* 3: Any 和 AnyObject 的类型转换
         
         */
        
        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)" })
        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")
            }
        }
        
        /* 3:
             Any类型表示了任意类型的值,包括可选类型。
             如果你给显式声明的Any类型使用可选项,Swift 就会发出警告。
             如果你真心需要在Any值中使用可选项,如下所示,你可以使用as运算符来显式地转换可选项为Any。
         */
        let optionalNumber: Int? = 3
        things.append(optionalNumber)        // Warning
        things.append(optionalNumber as Any) // No warning
    }
}

// 定义媒体项
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)
    }
}

 

posted on 2023-03-09 21:39  风zk  阅读(92)  评论(0编辑  收藏  举报

导航