在開始之前,先問問大家都看過第一篇了嗎? 還沒的話可以點這邊。
第一篇發佈之後的隔天,我點開了發佈出去的文章,想說看一下有沒有讀者回應,結果發現右上角有一堆通知,嚇了我一大跳! 我想說也太扯了吧,怎麼會有這麼多人看?結果點開通知一看,似乎是爬蟲機器人大軍進攻 方格子 vocus,在下面的留言區瘋狂洗版,我只好一則一則手動刪除QQ,希望這篇發布後不要再 Trigger 到什麼奇怪的開關,讓我的文章正常的擴散出去吧!
回來本篇的正題,繼上篇透過 Enum
來表示簡易的棒球規則,接下來我們要介紹的是如何用 Swift
,來優雅的表示棒球場上的佔壘狀況。
本篇的程式碼調整為使用gist嵌入,希望能幫助你閱讀。
我們先將棒球規則裡的佔壘狀況條列出來:
- 壘上無人
- 一壘有人
- 二壘有人
- 三壘有人
- 一、二壘有人
- 一、三壘有人
- 二、三壘有人
- 滿壘
在不認識 OptionSet
之前,我們可能會這樣寫:
這樣的寫法雖然可以表示佔壘狀況,但是當我們需要判斷佔壘狀況時,必須要同時判斷三個變數,這樣的寫法不夠優雅,也容易出錯。
這時候我們就可以使用 OptionSet
的特性,來表示佔壘狀況。 但在開始之前,讓我們先簡單認識一下,一些你可能用過,但不知道他是 OptionSet
的東西:
1. UIControl.State
我們常常在 UIButton
中,透過設定不同的 state
來顯示不同的外觀,例如:
我們點進 state
的屬性,可以看到:
由於 UIButton
繼承自 UIControl
,因此也一併得到了 state
屬性,那我們再來看看 UIControl.State
的定義:
我們可以看到,UIControl.State
是一個 OptionSet
,他可以表示按鈕的各種狀態,而與 Enum
不同的是,OptionSet
可以表示多個選項的組合,例如:
這樣的寫法,就表示按鈕在正常狀態和按下狀態下,都會顯示 Submit
這個文字。 如果說 Enum
是單選題,那 OptionSet
就是多選題,可以選擇多個答案。
2.UIRectCorner
、CACornerMask
在做圓角時,我們常常會使用 UIRectCorner
來表示圓角的各個角落,例如:
這樣的寫法,就表示圓角的左上角和右上角都會有圓角效果。
類似的用法還有 CACornerMask
,在繪製 layer
的圓角時,我們會使用 CACornerMask
來表示圓角的各個角落,例如:
這樣的寫法,就表示圓角的左上角和右上角都會有圓角效果。
除了這些,還有許多 OptionSet
的用法,例如 FileManager.DirectoryEnumerationOptions
、UIView.AutoresizingMask
等等,這些都是 Swift
原生的 OptionSet
用法。
回到我們的棒球佔壘狀況,我們可以這樣定義:
我們和前面一樣,有三個屬性分別表示三個壘包的佔壘狀況,而不同於前面使用 Bool
, OptionSet
在表示佔壘狀況時,會使用 Int
來表示,並且使用位元運算來表示佔壘狀況。
如果你不懂位元運算,這邊簡單解釋一下,位元運算就是將數字轉換成二進位,然後進行位元運算,用上面的例子來解釋的話:
firstBase
的值是1
// 二進位 001 (2的0次方)secondBase
的值是2
// 二進位 010 (2的1次方)thirdBase
的值是4
// 二進位 100 (2的2次方)
所以一二壘有人的狀況,就是 1 + 2 = 3
,而一三壘有人的狀況,就是 1 + 4 = 5
,以此類推,我們把全部的狀況,按照順序條列如下:
0
壘上無人1
一壘有人2
二壘有人3
一、二壘有人4
三壘有人5
一、三壘有人6
二、三壘有人7
滿壘
至此,我們已經簡單地完成了佔壘狀況的表示,接下來,讓我們用實際的球場狀況來說明,如何用 OptionSet
來表示佔壘狀況。
上面這些例子,相對於原先使用 Bool
來表示佔壘狀況,使用 OptionSet
來表示佔壘狀況,不僅更直覺,也更符合棒球場上的狀況。 你不需要在一次打擊時,同時去更動三個壘包的 Bool
值,你只需要更動一個 OptionSet
的值,就可以表示所有可能的佔壘狀況。
而另外,除了直接 set
佔壘狀況,我們還可以透過 OptionSet
內建的 function
,來為佔壘狀況做變化。 例如:
到這邊,我們已經簡單介紹了 OptionSet
的基本概念,並且透過實際的案例,讓你更了解 OptionSet
的用法。
我們可以整理一下,OptionSet
的優勢:
- 直覺的語法:使用
[.firstBase, .thirdBase]
這樣的語法簡單易懂 - 效率高:底層使用位元運算,非常高效
- 組合靈活:可以輕鬆組合和比較各種狀態
- 內建集合操作:提供
contains
、insert
、remove
等實用方法 - 節省記憶體:多個狀態只需使用一個整數儲存
以上就是這次的內容,有別於前一篇提過的 Enum
,這次我們介紹了 OptionSet
的用法,希望這篇文章能夠幫助你更了解 OptionSet
的用法。 你還有感受到哪些 Swift
Moment,是你在棒球場上常常遇到的嗎?可以在底下留言和大家分享!
如果覺得這篇文章對你有幫助,也歡迎分享給更多人知道,或者還有想了解的 Swift
技巧,也歡迎留言告訴我!
本篇文章程式碼部分由 AI
輔助產生。