Swift的學(xué)習(xí)過程
swift的學(xué)習(xí):
-
常量: 用let關(guān)鍵字聲明, 一旦聲明(聲明時必須初始化),即不可以修改值, 因?yàn)椴荒苄薷? 所以也不必指定具體類型, Swift會自動判斷該常量值的類型.
let country = "China"
-
變量: 用var關(guān)鍵字聲明, 聲明變量之后,定義其初始值的表達(dá)式, 在聲明的同時初始化變量并不是必須的, 但是你必須在使用它之前進(jìn)行初始化. 因?yàn)槿绻氵@樣做,Swift就可以推斷變量的類型,這樣就為你省掉了明確指定類型的麻煩.
> 如下例子中: Swift推斷str為一個字符串變量, 因?yàn)槟阋呀?jīng)將其初始化為一個字符串. > 但是如果你不選擇提供初始化,那么必須將變量類型添加在變量名之后,也就是用冒號:隔開 > var str = "daejong" > var str : String?
Optional類型
1.Optional類型也是Objectvie-C沒有的數(shù)據(jù)類型.
2.在OC中只有對象才能為nil, 而在Swift中,當(dāng)基礎(chǔ)類型(Int, Float, Bool等)沒有值的時候, 也是nil.
3.沒有初始值的變量是不能夠使用的. 于是乎就產(chǎn)生了Optional類型.
4. 定義一個Optional的值很容易,只需要在類型后面加上問號即可(?).
代碼如下
var str : String?
一個Optional值和非Optional值的區(qū)別就在于: Optional值沒有初始化時也是nil值, 但是普通的變量連nil都沒有
注意什么都沒有的變量是不能被使用的, 一旦使用會報錯
代碼如下
//未被初始化,但是是一個Optional類型, 即為nil
var str : String?
str //nil
//未被初始化, 也不是Optional類型
var str2 : String
str2 //使用時出錯
Optional的拆包
-
顯示拆包
由于Optional類型的值不能被直接使用, 當(dāng)需要的時候要顯示拆包, 以表明我知道這個Optional是一定有值的.
代碼如下
var str : String? = "daejong" str! //daejong //對比拆包前后, str的輸出如下 str //{Some :daejong"} str! // daejong
之所以要拆包使用,因?yàn)镺ptional類型其實(shí)是一個枚舉
enum Optional<T> : Reflectable, NilLiteralConvertible { case None case Some(T) init() init(_ some: T) /// Haskell's fmap, which was mis-named func map<U>(f: (T) -> U) -> U? func getMirror() -> MirrorType static func convertFromNilLiteral() -> T? }
當(dāng)Optional沒有值的時候, 返回的nil其實(shí)就是optional.None, 即沒有值. 除了None之外,還有一個Some, 當(dāng)有值的時候就是被Some<T>包裝的真正的值, 所以這才需要我們進(jìn)行拆包->將Some里面的值取出來(類似java中的泛型).
-
隱式拆包
除了顯示拆包,Optional還提供了隱式拆包, 通過在聲明變量的時候在數(shù)據(jù)類型后面加上一個感嘆號來實(shí)現(xiàn)(!).
代碼如下
var str : String! = "daejong" str //daejong
其實(shí)這個語法等于告訴編譯器: 在我們使用該Optional值之前, 這個Optional值就會被初始化,并且總會有值, 所以當(dāng)我們使用該變量的時候, 編譯器就會幫我們做一次拆包. 當(dāng)然如果你確定你的變量在使用之前一定會被初始化(即有值), 那么大可這么做, 否則還是不要嘗試為好.
可選綁定 Optional Binding
-
不用可選綁定的情況如下
代碼如下
var count : Int? count = 1000 if count != nil { "count is " + String(count!) //這里要進(jìn)行顯示拆包 }
為了避免在條件判斷語句后執(zhí)行一次或者多次的拆包, Swift引進(jìn)了Optional Binding
-
使用可選綁定 如下
代碼如下
var count : Int? count = 1000 if let validCount = count { "count is " + String(validCount) //注意這里的不同 }
通過在條件判斷語句中(if或者while等中)把Optional值直接賦值給一個臨時常量, Swift會自動檢測Optional是否包含值, 如果包含值, 則會隱式的拆包并賦值給那個臨時常量, 這樣就可以在接下來的下文中直接使用該臨時常量了, 從而避免了一次次的顯示拆包
其實(shí), Optional Bindiing中, 除了以常量的方式去接收拆包的值, 也可以用變量的形式去接收, 但是大多數(shù)情況下, 我們只是使用那個值就行了, 并不會去改變它.
Optional Chaining
-
用處:
相對于簡單類型(Int, String等), Optional更主要的應(yīng)用場景是在復(fù)雜的對象上, 當(dāng)一個對象包含另一個對象, 同時這個對象都有可能為nil的情況下才是Optional派上用場的地方. 在OC中,想nil發(fā)送消息得到是一個nil, 但是Swift不能在nil上直接調(diào)用方法或者屬性, 從而引入了Optional類型, 來防止一個對象中的一個對象為nil情況的發(fā)生.
代碼如下
//一個人 class Person { var pet: Pet? } //一個人有一個寵物 class Pet { var name: String! var favoriteToy: Toy? init (name: String) { self.name = name } } //一個寵物有一個玩具 class Toy { var name: String! init (name: String) { self.name = name } }
那么該如何過去到玩具的名稱呢?
代碼如下
let daejong = Person() daejong.pet = Pet(name : "dog") daejong.pet?.favoriteToy = Toy(name : "iPhone") if let pet = daejong.pet { if let toy = pet.favoriteToy { toy.name } }
這里用到了兩個if, 因?yàn)閜et和toy對象都有可能為nil, 我們要預(yù)防每一個可能為nil的對象, 如果這個對象在復(fù)雜點(diǎn), 那if的判斷也就會跟著增多,
-
但是如果使用Optional Chaining的話, 寫出來就是如下效果:
代碼如下
let daejong = Person() daejong.pet = Pet(name : "dog") daejong.pet?.favoriteToy = Toy(name : "iPhone") //這里進(jìn)行一個Optional值調(diào)用另一個Optional值, 形成Optional Chaining if let toy = daejong.pet?.favoriteToy { toy.name }
當(dāng)一個Optional值調(diào)用它的另外一個Optional值的時候, 這個時候 Optional Chaining就形成了. 基本上, Optional Chaining總是會返回一個Optional的值, 只要這個Chaining中有一個值為nil, 整條chain就為nil, 和OC中的向nil發(fā)送消息一樣.