[Live in Swift] Vol. 1 用棒球規則認識 Enum 的威力

更新於 發佈於 閱讀時間約 12 分鐘

Enum的威,Enum的力,Enum的威力,一粒????


你看棒球比賽嗎? 棒球是我們台灣的國球,在台灣有許許多多的球迷,筆者也從國中時代開始,就深深地感受到棒球的魅力,不論是下課回家盯著電視,或者直接走進棒球場,享受著棒球帶來的熱血與激情!

How can you not be romantic about baseball?

在這篇文章中,我們將走進棒球場中,帶你一步步認識 Swift 中 Enum 的特性,感受棒球場上的 Swift Moment。

從最基本的定義,到進階的 Nested EnumAssociated Value,最後再介紹如何透過 CustomStringConvertible 來嘗試製作比賽紀錄。

這些技巧不只能幫助你寫出更有結構的程式,也讓你對 Enum 有更深入的理解。

從守備位置認識 Enum 的基本特性

讓我們先從最基本的定義開始吧!

Swift 的 Enum 非常適合用來表示 「狀態有限、規則清晰」 的資料。

什麼是 「狀態有限、規則清晰」 ?

舉例來說,一場棒球比賽中,一隊有九個守備位置,每個位置名稱固定、不會重複,也不會出現第十種或-1種位置,這正好適合用 Enum 來表示。

enum FieldPosition {
case pitcher
case catcher
case firstBase
case secondBase
case thirdBase
case shortstop
case leftField
case centerField
case rightField
}

每一個 case 就像一位選手的位置,它的名稱唯一、型別固定,能幫助我們用程式清楚表達狀態,避免寫錯。

俄羅斯套娃的 Nested Enum !?進一步分類守備位置

當我們希望更進一步區分內野、外野、其他守備角色時,就可以使用巢狀 Enumnested enum)。這可以幫助我們把不同類型的守備位置分門別類地整理起來。

enum PositionGroup {
enum Battery: Int {
case pitcher = 1
case catcher = 2
}

enum Infield: Int {
case firstBase = 3
case secondBase = 4
case thirdBase = 5
case shortstop = 6
}

enum Outfield: Int {
case leftField = 7
case centerField = 8
case rightField = 9
}

case battery(Battery)
case infield(Infield)
case outfield(Outfield)
}

這裡除了做分類,也幫每個位置標上了守備紀錄常用的編號,方便日後進行進一步紀錄。

使用 Associated Aalue 來描述打擊結果

Swift 的 Enum 也能為每個 case 搭配額外資訊,讓 Enum 更靈活,如同我們上面用到的 case battery(Battery),這就是 Associated Value 的一種。

我們可以進一步設計一個 Enum 來描述打擊結果,並且使用 Associated Value 來描述打擊結果的細節。

enum BattingResult {
case strikeOut
case flyOut(to: FieldPosition)
case groundOut(to: FieldPosition)
case hit(HitType)
case doublePlay(involvedFielders: [FieldPosition])
case error(by: FieldPosition)

enum HitType {
case single
case double
case triple
case homeRun
}
}

Associated Value 除了 Enum 之外,也可以放入其他型別,例如 IntStringBool 或者自定義的 class 或 struct

這樣的設計讓 enum 更有彈性,可以根據不同情況儲存對應的資料。


CaseIterable:我要全部!

如果我們希望列出某個 Enum 所有的 case,可以讓它遵守 CaseIterable

enum FieldPosition: CaseIterable {
case pitcher, catcher, firstBase, secondBase, thirdBase, shortstop, leftField, centerField, rightField
}

for position in FieldPosition.allCases {
print(position)
}

這對製作選單、驗證資料、或者在單元測試中產生所有可能值非常實用。


用 CustomStringConvertible 讓 Enum 更容易紀錄與顯示

當我們需要把 Enum 的值用文字清楚地表達出來(例如做 log 或畫面顯示),可以透過遵守 CustomStringConvertible 協定來達成。

當我們的 Enum 遵守 CustomStringConvertible 時,需要加上 description 的實作來滿足 CustomStringConvertible 協定。

extension FieldPosition: CustomStringConvertible {
var description: String {
switch self {
case .pitcher: return "投手"
case .catcher: return "捕手"
case .firstBase: return "一壘手"
case .secondBase: return "二壘手"
case .thirdBase: return "三壘手"
case .shortstop: return "游擊手"
case .leftField: return "左外野手"
case .centerField: return "中外野手"
case .rightField: return "右外野手"
}
}
}

除了 FieldPosition,我們也可以幫打擊結果加上描述:

extension BattingResult: CustomStringConvertible {
var description: String {
switch self {
case .strikeOut:
return "三振"
case .flyOut(let to):
return "飛球出局(由 \(to) 接殺)"
case .groundOut(let to):
return "滾地球出局(由 \(to) 處理)"
case .hit(let type):
return "打出一支 \(type)"
case .doublePlay(let involvedFielders):
let sequence = involvedFielders.map { "\($0.rawValue)" }.joined(separator: "-")
return "雙殺 \(sequence)"
case .error(let by):
return "守備失誤(由 \(by))"
}
}
}

extension BattingResult.HitType: CustomStringConvertible {
var description: String {
switch self {
case .single: return "一壘安打"
case .double: return "二壘安打"
case .triple: return "三壘安打"
case .homeRun: return "全壘打"
}
}
}

這樣我們就可以清楚紀錄像是:

let result1: BattingResult = .doublePlay(involvedFielders: [.shortstop, .secondBase, .firstBase])
print(result1.description) // 雙殺 6-4-3

let result2: BattingResult = .hit(.single)
print(result2.description) // 打出一支 一壘安打

let result3: BattingResult = .strikeOut
print(result3.description) // 三振

用這種方式,我們可以靈活記錄比賽過程中發生的各種狀況,也讓程式碼更有可讀性與可維護性。


以上,我的第一篇方格子 Swift 教學文章,我們用棒球場上的守備位置、打擊結果、以及比賽過程,介紹了Enum 的基本特性,以及如何透過 CustomStringConvertible 來讓 Enum 更容易紀錄與顯示。

這些技巧不只能幫助你寫出更有結構的程式,也讓你對 Enum 有更深入的理解。

希望這篇文章能夠幫助你更了解 Enum 的威力,有時間的話也不妨走進球場,感受棒球帶來的熱血與激情!

如果還有其他你發現的 Swift Moment,也歡迎留言分享,多多交流!


*本篇文章程式碼部分由 `AI` 輔助產生。

留言
avatar-img
留言分享你的想法!
avatar-img
Rice把拔的生活與開發筆記
0會員
16內容數
這裡是我的開發與生活筆記。 分享iOS開發經驗、教學技巧,也記錄生活中的點滴與觀察。 偶爾來點評論,輕鬆聊聊技術與日常。
你可能也想看
Thumbnail
孩子寫功課時瞇眼?小心近視!這款喜光全光譜TIONE⁺光健康智慧檯燈,獲眼科院長推薦,網路好評不斷!全光譜LED、180cm大照明範圍、5段亮度及色溫調整、350度萬向旋轉,讓孩子學習更舒適、保護眼睛!
Thumbnail
孩子寫功課時瞇眼?小心近視!這款喜光全光譜TIONE⁺光健康智慧檯燈,獲眼科院長推薦,網路好評不斷!全光譜LED、180cm大照明範圍、5段亮度及色溫調整、350度萬向旋轉,讓孩子學習更舒適、保護眼睛!
Thumbnail
創作者營運專員/經理(Operations Specialist/Manager)將負責對平台成長及收入至關重要的 Partnership 夥伴創作者開發及營運。你將發揮對知識與內容變現、影響力變現的精準判斷力,找到你心中的潛力新星或有聲量的中大型創作者加入 vocus。
Thumbnail
創作者營運專員/經理(Operations Specialist/Manager)將負責對平台成長及收入至關重要的 Partnership 夥伴創作者開發及營運。你將發揮對知識與內容變現、影響力變現的精準判斷力,找到你心中的潛力新星或有聲量的中大型創作者加入 vocus。
Thumbnail
這篇內容,將會講解什麼是變數,以及與變數相關的知識。包括變數、資料型態、變數賦值、變數的命名規則、變數的作用區域、變數的可重複性、內建變數。
Thumbnail
這篇內容,將會講解什麼是變數,以及與變數相關的知識。包括變數、資料型態、變數賦值、變數的命名規則、變數的作用區域、變數的可重複性、內建變數。
Thumbnail
高中數學主題練習—圓一般式化標準式
Thumbnail
高中數學主題練習—圓一般式化標準式
Thumbnail
高中數學主題練習—指數律基本練習
Thumbnail
高中數學主題練習—指數律基本練習
Thumbnail
高中數學主題練習—指數律基本練習
Thumbnail
高中數學主題練習—指數律基本練習
Thumbnail
高中數學主題練習—根式化簡
Thumbnail
高中數學主題練習—根式化簡
Thumbnail
高中數學主題練習—根式化簡
Thumbnail
高中數學主題練習—根式化簡
Thumbnail
本章節介紹了程式語言中的各種運算符,包括算數運算子、比較運算子、賦值運算子、位元運算子,以及運算子的優先等級。每種運算子都有對應的範例程式碼和輸出結果,以幫助讀者更好地理解其用法和效果。此外,章節也強調了運算子的優先等級在程式設計中的重要性,並通過範例展示了不同優先等級的運算順序對運算結果的影響。
Thumbnail
本章節介紹了程式語言中的各種運算符,包括算數運算子、比較運算子、賦值運算子、位元運算子,以及運算子的優先等級。每種運算子都有對應的範例程式碼和輸出結果,以幫助讀者更好地理解其用法和效果。此外,章節也強調了運算子的優先等級在程式設計中的重要性,並通過範例展示了不同優先等級的運算順序對運算結果的影響。
Thumbnail
此章節旨在介紹Swift程式語言中的基本資料型別,包括整數、浮點數、布林型別、字串、字符、選擇型、型別轉換、自訂型別(包括類、結構和枚舉)、元組型別、集合型別、陣列型別和字典型別。每種型別的說明都包含了程式碼範例,以便讀者更好地理解其應用和使用方式。
Thumbnail
此章節旨在介紹Swift程式語言中的基本資料型別,包括整數、浮點數、布林型別、字串、字符、選擇型、型別轉換、自訂型別(包括類、結構和枚舉)、元組型別、集合型別、陣列型別和字典型別。每種型別的說明都包含了程式碼範例,以便讀者更好地理解其應用和使用方式。
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News