25
? ! 略懂略懂 (Optional in Swift Grady Zhuo github.com/gradyzhuo facebook.com/gradyzhuo

Optional in swift

Embed Size (px)

Citation preview

Page 1: Optional in swift

? 和 ! 略懂略懂 (︖?!

Optional in Swift Grady Zhuogithub.com/gradyzhuofacebook.com/gradyzhuo

Page 2: Optional in swift

什麼是Optional - 1❖ Swift also introduces optional types, which handle the

absence of a value. Optionals say either “there is a value, and it equals x” or “there isn’t a value at all”. Optionals are similar to using nil with pointers in Objective-C, but they work for any type, not just classes. Optionals are safer and more expressive than nil pointers in Objective-C and are at the heart of many of Swift’s most powerful features.

Page 3: Optional in swift

什麼是Optional - 2❖ Optional是Swift中,做為處理可能存在nil值變數的機制。︒

❖ Optional 是⼀一個enum,存在兩種可能:

❖ Some : 有值存在

❖ None : 無值存在———————————————————————— enum Optional<T> : Reflectable, NilLiteralConvertible { case None case Some(T) }

Page 4: Optional in swift

開始囉

會爆炸的包裹

這個世界裡的包裹,拆開後,如果沒有東西,世界就會毀滅…

Page 5: Optional in swift

別讓上帝不開⼼心

❖ 我們先假設這個世界裡的包裹,拆開後,如果沒有東西,拆上帝就會爆⾛走,然後世界就毀滅了(咦?

❖ 可以要求別⼈人在送包裹的時候,要把東西放在箱⼦子給你。︒

❖ 你隨時可以拆包裹,只是要⼩小⼼心,世界,可能會毀滅…

Page 6: Optional in swift

放進禮物盒❖ 所謂的“放進箱⼦子”這個動作就是由「?」來達成。︒

❖ 我們可以想像成,當你宣告使⽤用了「?」,就像是你準備了⼀一個箱⼦子準備放物品,箱⼦子上⾯面會貼標籤說明這是什麼東西。︒

❖ 當你賦值時,就像是把⼀一個東西放入了「箱⼦子」中,雖然包裹的標籤有說這是什麼東西,但你拿到的還是「盒⼦子」。︒

Int?

String?CGRect?

Page 7: Optional in swift

「?」 做了什麼事呢︖?❖ 「?」 是什麼︖? 「?」是 Optional<T> 的「語法糖衣1」

❖ e.g. 有值的狀況

var i : Int? = 10

var i : Optional<Int> = Optional<Int>.Some(10)

❖ e.g. 沒有值的狀況

var j : Int? = nil

var j : Optional<Int> = Optional<Int>.None

Page 8: Optional in swift

開箱

❖ 開箱這檔事,就是「!」這把「⼑刀」負責。︒

❖ 「!」在術語中又叫 Unwrap

❖ 為什麼「!」最讓⼈人困惑︖?

❖ 因為「!」要分兩種情況說明:

❖ 1. 作為運算⼦子

❖ 2.宣告

!

Page 9: Optional in swift

先說說運算⼦子的狀況

❖ 你可以針對任何Optional的值進⾏行Unwrap

❖ 就像東西重新從箱⼦子又拿出來的意思

❖ e.g. 考慮有值的Optional

❖ var i : Int? = 3

❖ i => Optional(3)

❖ var unwrappedValue = i! => 3 //重新把3拿出來

Page 10: Optional in swift

先說說運算⼦子的狀況

❖ e.g. 如果是沒有值的Optional

❖ var j:Int? = nil

❖ j => Optional(nil)

❖ j! => nil //就會拿到nil了~

Page 11: Optional in swift

先說說運算⼦子的狀況

❖ e.g. 如果是沒有值的Optional

❖ var j:Int? = nil

❖ j => Optional(nil)

❖ j! => nil //就會拿到nil了

因為當運算⼦子的「!」 是unwrapping, 所以⼀一定要取到東西

會Crash!!!!

Page 12: Optional in swift

宣告時⽤用的「!」❖ 宣告的狀況下,「!」跟「?」的⾏行為類似, 都可以塞進nil。︒

❖ 但使⽤用時,如果是nil,就會Crash...(Why?

❖ e.g. 有值的狀況

var i : Int! = 3

var k = i + 1 => 3 //不是Optional

❖ e.g. 沒有值的狀況

var j : Int!

var l = j + 1 //Crash

Page 13: Optional in swift

宣告時的「!」,做了什麼︖? - 1❖ 宣告時使⽤用「!」就像在箱⼦子旁邊貼著⼀一把「⼑刀」,這把⼑刀就像被動技能⼀一樣,只要操作variable,就會⾃自動啟動Unwrapping。︒

❖ e.g. 剛剛有值的例⼦子

❖ var i : Int! = 3

❖ var k = i + 1 => 3

//所以上⾯面的寫法,會等於下⾯面的寫法。︒

❖ var i : Int? = 3

❖ var k = i! + 1 => 3 //因為i有值,所以unwrap有值,⼀一切正常。︒

錢鬼,我還你原形!(誤

Page 14: Optional in swift

宣告時的「!」,做了什麼︖? - 2

//同理,回來討論nil的狀況

var j : Int!

var l = j + 1 //Crash

//等於下⾯面寫法

var j : Int?

var l = j! + 1 //因為j沒有值,是個nil, 所以會Crash,⽽而且crash在j!的地⽅方

Page 15: Optional in swift

宣告時⽤用「!」跟「︖?」的不同

❖ 「?」:就是你想⽤用這個參數時,你必須先找⼀一把⼑刀⼦子才能開箱,所以Xcode會強迫你去處理Optional的變數。︒

❖ 「!」:因為Unwrap會⾃自動進⾏行,所以⽤用「!」的變數跟沒有宣告Optional⼀一樣,可以直接使⽤用變數的值,所以可以不⽤用進⾏行任何處理,但就會出現隱憂,程式隨時都會Crash.

Page 16: Optional in swift

使⽤用時該怎麼選呢︖?

Page 17: Optional in swift

除非除非除非(很重要,所以說三次)你很確定,這個變數裡⼀一定有值,只是現在宣告沒辦法先給,那你就可以⽤用「!」

e.g.

1. 與UI連動的@IBOutlet,因為你⼀一定會連到某⼀一個UI上,只是因為宣告不可能給實體,所以你就可以先設定成「!」。︒

(通常你不拉這個outlet,程式也運⾏行不正確)

2. 你了解⾃自已的架構,會正確無誤,那也可以⽤用「!」宣告。︒

總⽽而⾔言之,⾔言⽽而總之

不要為了「懶」⽽而使⽤用「!」,⼑刀劍無情!

⼈人在江湖漂,那有不挨⼑刀(︖?

Page 18: Optional in swift

兩個⼩小技巧

❖ 在拆包裹時,你可以選擇引發神蹟,如果本來沒東西,至少會冒出個⼩小確幸可以拿到。︒(別讓⾃自已不開⼼心

❖ 如果包裹有好幾層,你也可以選擇躲在箱⼦子裡拆包裹,然後可能就在箱⼦子裡⾃自爆了。︒(︖?

Page 19: Optional in swift

??❖ Swift導入了 「??」⼆二元運算⼦子,他的規則如下:

❖ (Value) = Optional(T) ?? (Default Value)

❖ 如果「??」左邊為nil, 會回傳「??」右邊的的值(通常是Default值)

❖ e.g.

❖ var i : Int? = 3

❖ var j = i ?? 0 // j == 3

❖ ——————————-

❖ var i:Int?

❖ var j = i ?? 0 // j == 0

Page 20: Optional in swift

Optional Chaining❖ Optional chaining is a process for querying and calling properties,

methods, and subscripts on an optional that might currently be nil.

❖ 可以在好幾層的Optional中使⽤用「?.」的語法取值操作,若過程中有任何操作出現nil, 會直接回傳nil, 且接下來的事情都不會進⾏行,也不會crash。︒

❖ var array:[Int]? = []

❖ array?.append(0)

❖ //

❖ var array2:[Int]?

❖ array2?.append(1) //不會crash, 且什麼事都不會發⽣生

Page 21: Optional in swift

補充

Page 22: Optional in swift

What is enum枚舉是⼀一個被命名的整型常數的集合,枚舉在⽇日常⽣生活中很常⾒見,例如表⽰示星期的SUNDAY、MONDAY…SATURDAY就是⼀一個枚舉。 枚舉的說明與結構相似,其形式為:

enum 集合命名[:元素的類型]{ case 元素1[=值] case 元素2[=值] ... case 元素n[=值] }

enum Week : Int{ case SUNDAY = 0 case MONDAY = 1 case TUESDAY = 2 case WEDNESDAY = 3 case THURSDAY = 4 case FRIDAY = 5 case SATURDAY = 6 }

Page 23: Optional in swift

enum in Swift

//: Swift中的enum有⼀一個特例的⽤用法,那就是可以塞東⻄西

enum MyEnum { case Value(str:String) }

//: 這樣我們可以做出許多都是MyEnum的enum變數,但內容不⼀一樣

var enum1 = MyEnum.Value(str: "Hello") var enum2 = MyEnum.Value(str: "World")

Page 24: Optional in swift

enum in Swift//: 也可以取出他們的值 func getValue(enumValue:MyEnum)->String{ switch enumValue { case let .Value(str): return str } }

let enum1Value = getValue(enum1) //enum1Value == “Hello” let enum2Value = getValue(enum2) //enum2Value == “World”

Page 25: Optional in swift

名詞解釋

❖ 語法糖衣:使⽤用更簡潔的語法,簡化原本較為繁瑣但完整的語法。︒