版本記錄
版本號 | 時間 |
---|---|
V1.0 | 2017.08.01 |
前言
我是swift2.0的時候開始接觸的,記得那時候還不是很穩定,公司的項目也都是用oc做的,并不對swift很重視,我自己學了一段時間,到現在swift3.0+已經出來了,自己平時也不寫,忘記的也差不多了,正好項目這段時間已經上線了,不是很忙,我就可以每天總結一點了,希望對自己對大家有所幫助。在總結的時候我會對比oc進行說明,有代碼的我會給出相關比對代碼。
1. swift簡單總結(一)—— 數據簡單值和類型轉換
2. swift簡單總結(二)—— 簡單值和控制流
3. swift簡單總結(三)—— 循環控制和函數
4. swift簡單總結(四)—— 函數和類
5. swift簡單總結(五)—— 枚舉和結構體
6. swift簡單總結(六)—— 協議擴展與泛型
7. swift簡單總結(七)—— 數據類型
8. swift簡單總結(八)—— 別名、布爾值與元組
9. swift簡單總結(九)—— 可選值和斷言
10. swift簡單總結(十)—— 運算符
11. swift簡單總結(十一)—— 字符串和字符
12. swift簡單總結(十二)—— 集合類型之數組
13. swift簡單總結(十三)—— 集合類型之字典
14. swift簡單總結(十四)—— 控制流
15. swift簡單總結(十五)—— 控制轉移語句
16. swift簡單總結(十六)—— 函數
17. swift簡單總結(十七)—— 閉包(Closures)
18. swift簡單總結(十八)—— 枚舉
19. swift簡單總結(十九)—— 類和結構體
20. swift簡單總結(二十)—— 屬性
21. swift簡單總結(二十一)—— 方法
22. swift簡單總結(二十二)—— 下標腳本
23. swift簡單總結(二十三)—— 繼承
24. swift簡單總結(二十四)—— 構造過程
25. swift簡單總結(二十五)—— 構造過程
26. swift簡單總結(二十六)—— 析構過程
27. swift簡單總結(二十七)—— 自動引用計數
28. swift簡單總結(二十八)—— 可選鏈
類型轉換
類型轉換可以判斷實例的類型,也可以將實例看做是其父類或者子類的實例。類型轉換在swift
中使用is
或as
操作符實現,這兩個操作符提供了一種簡單達意的方式去檢查值的類型或者轉換它的類型。你也可以用來檢查一個類是否實現了某個協議。
這篇主要從下面幾個方面進行說明。
- 定義一個類層次作為例子
- 檢查類型
- 向下轉型
Downcasting
-
Any
和AnyObject
的類型轉換
定義一個類層次作為例子
你可以將它用來類和子類的層次結構上,檢查特定類實例的類型并轉換這個類實例的類型成為這個層次結構中的其他類型,這下面的三個代碼段定義了一個類層次和一個包含了幾個這些類實例的數組,作為類型轉換的例子。
先看第一段代碼。
class MediaItem {
var name : String
init(name : String) {
self.name = name
}
}
定義了一個新的基礎類MediaItem
,聲明一個name
屬性,和一個init(name : String)
的初始化器。
接著看第二段代碼。
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)
}
}
新定義的兩個類都繼承自MediaItem
,其中類Movie
新增了一個屬性導演director
,類Song
新增了一個屬性artist
。
下面代碼創建了一個數組常量library
,包含兩個Movie
實例和三個Song
實例。swift
可以推斷出MediaItem []
類作為library
的類型。
class JJPracticeVC: UIViewController {
override func viewDidLoad()
{
super.viewDidLoad()
view.backgroundColor = UIColor.lightGray
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
里存儲的媒體項依然是Movie
和Song
類型的,但是,若迭代它,取出的實例會是MediaItem
類型時,而不是Movie
和Song
類型的。
檢查類型 - Checking Type
用類型檢查操作符is
來檢查一個實例是否是屬于特定子類型,若實例屬于那個子類型,類型檢查操作符會返回true
,否則返回false
。
下面看一下簡單的代碼。
class JJPracticeVC: UIViewController {
override func viewDidLoad()
{
super.viewDidLoad()
view.backgroundColor = UIColor.lightGray
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("song -- \(songCount)")
print("movie -- \(movieCount)")
}
}
下面看輸出結果
song -- 3
movie -- 2
代碼中movieCount
和songCount
分別用來計算Movie
和Song
實例的個數。
向下轉型 - Downcasting
某類型的一個常量或者變量可能在幕后實際上屬于一個類,你可以嘗試向下轉到它的子類型,用類型轉換操作符as
。因為向下轉型可能會失敗,類型轉換操作符帶有兩種不同的形式,可選形式as?
和強制形式as
,強制形式as
把試圖向下轉型和強制解包(force - unwraps)
結果作為一個混合動作。
當你不確定向下轉型可以成功時,用類型轉換的可選形式as?
,只有你確定向下轉型一定會成功時,才使用強制形式。
下面看一個簡單例子
class JJPracticeVC: UIViewController {
override func viewDidLoad()
{
super.viewDidLoad()
view.backgroundColor = UIColor.lightGray
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")
]
for item in library {
if let movie = item as? Movie{
print("Movie:\(movie.name),\(movie.director)")
}
else if let song = item as? Song{
print("Song:\(song.name),\(song.artist)")
}
}
}
}
下面看輸出結果
Movie:Casablanca,Michael Curtiz
Song:Blue Suede Shoes,Elvis Presley
Movie:Citizen Kane,Orson Welles
Song:The one And Only,Chesney Hawkes
Song:Never Gonna Give You Up,Rick Astley
轉換并沒有真的改變實例或它的值,潛在的根本的實例保持不變,只是簡單的把它作為它被轉換成類來使用。
Any 和 AnyObject 的類型轉換
swift
為不確定類型提供了兩種特殊類型別名:
-
AnyObject
可以代表任何class
類型的實例 -
Any
可以表示任何類型,除了方法類型function types
注意:只有你明確的需要它的行為和功能時才會使用Any
和AnyObject
,在你的代碼里使用你期望的明確的類型總是更好的。
1. AnyObject 類型
當需要在工作中使用Cocoa APIs
,它一般接收一個AnyObject[]
類型的數組,或者說一個任何對象類型的數組,這是因為OC
沒有明確的類型化數組。
下面定義了一個AnyObject[]
類型的數組。
let someObject : [AnyObject] = [
Movie(name: "Casablanca", director: "Michael Curtiz"),
Movie(name: "Moon", director: "Duncan Jones"),
Movie(name: "Alien", director: "Ridley Scott")
]
因為知道這個數組都是Movie
實例,所以可以直接用as
下轉強制解包。下面調用一下。
class JJPracticeVC: UIViewController {
override func viewDidLoad()
{
super.viewDidLoad()
view.backgroundColor = UIColor.lightGray
let someObject : [AnyObject] = [
Movie(name: "Casablanca", director: "Michael Curtiz"),
Movie(name: "Moon", director: "Duncan Jones"),
Movie(name: "Alien", director: "Ridley Scott")
]
for object in someObject {
let movie = object as! Movie
print("Movie:\(movie.name),\(movie.director)")
}
}
}
下面看一下輸出結果
Movie:Casablanca,Michael Curtiz
Movie:Moon,Duncan Jones
Movie:Alien,Ridley Scott
2. Any 類型
這里使用Any
類型來混合的不同類型一起工作,包括非class
類型,它創建了一個可以存儲Any
類型的數組things
。
var things = [Any]()
things.append(0)
things.append(0.0)
things.append("hello")
things.append((3.0, 5.0))
things.append(Movie(name: "Ghost", director: "Ivan"))
print(things)
看輸出結果
[0, 0.0, "hello", (3.0, 5.0), JJSwift.Movie]
下面在switch case
里面用as
操作符查找每一項的類型,下面看一下代碼。
class JJPracticeVC: UIViewController {
override func viewDidLoad()
{
super.viewDidLoad()
view.backgroundColor = UIColor.lightGray
var things = [Any]()
things.append(0)
things.append(0.0)
things.append(42)
things.append(3.14259)
things.append("hello")
things.append((3.0, 5.0))
things.append(Movie(name: "Ghost", director: "Ivan"))
print(things)
for thing in things {
switch thing {
case 0 as Int:
print("zero is an Int")
case 0 as Double:
print("zero is an Double")
case let someInt as Int:
print("an integer of \(someInt)")
case let someDouble as Double where someDouble > 0:
print("an double of \(someDouble)")
case is Double:
print("some double did not print")
case let someString as String:
print("an string of \(someString)")
case let (x, y) as (Double, Double):
print("an (x, y) of \(x), \(y)")
case let movie as Movie:
print("an movie called \(movie.name), director is \(movie.director)")
default:
print("something else")
}
}
}
}
下面看輸出結果
[0, 0.0, 42, 3.1425900000000002, "hello", (3.0, 5.0), JJSwift.Movie]
zero is an Int
zero is an Double
an integer of 42
an double of 3.14259
an string of hello
an (x, y) of 3.0, 5.0
an movie called Ghost, director is Ivan
注意:在一個switch
語句的case
中使用強制形式的類型轉換操作符as
來檢查和轉換到一個明確的類型,在switch - case
語句的內容中這種檢查總是安全的。
后記
未完,待續~~~