在開始之前,先問問大家都看過第一篇了嗎? 還沒的話可以點這邊。
第一篇發佈之後的隔天,我點開了發佈出去的文章,想說看一下有沒有讀者回應,結果發現右上角有一堆通知,嚇了我一大跳! 我想說也太扯了吧,怎麼會有這麼多人看?結果點開通知一看,似乎是爬蟲機器人大軍進攻 方格子 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 輔助產生。



















