Protocol OptionSet
Published in
5 min readSep 16, 2022
除了 Enum ,你還有 OptionSet 呀
OptionSet 協議:
A type that presents a mathematical set interface to a bit set.
一種透過不同位元組合表示不同選項的枚舉類型。
OptionSet 和 Enum 皆為枚舉類型:
Enum 為通用枚舉
OptionSet 則能存在多種元素組合
若變數行為像「單選題」可使用 Enum
「多選題」則可選擇使用 OptionSet。
Let’s Code:
OptionSet 聯絡資訊 為例
聯絡資訊: 姓名、電話、信箱、地址
struct Contact: OptionSet {
let rawValue: Int //⭐️required property static let name = Contact( rawValue: 1 << 0 ) //0001
static let phone = Contact( rawValue: 1 << 1 ) //0010
static let email = Contact( rawValue: 1 << 2 ) //0100
static let address = Contact( rawValue: 1 << 3 ) //1000
static let mustHave: Contact = [ name, phone ]
static let all: Contact = [ name, phone, email, address ]
}print(Contact.name) //Contact(rawValue: 1)
print(Contact.phone) //Contact(rawValue: 2)
print(Contact.email) //Contact(rawValue: 4)
print(Contact.address) //Contact(rawValue: 8)
使用 1 << 0
進行位元進位運算,透過不同 bit 表示不同選項。
OptionSet 能存在多種元素集合,分別組了兩組組合,必填欄位 和 所有欄位:
static let mustHave: Contact = [ name, phone ]
static let all: Contact = [ name, phone, email, address ]print(Contact.mustHave) //Contact(rawValue: 3) = 1+2
print(Contact.all) //Contact(rawValue: 15) = 1+2+4+8
要注意的是每個 static properties 本質上還是一個「集合」的概念,就算只包含一個元素都是如此!
//以下皆為集合
var singleOption: Contact = .name
var mustHaveOptions: Contact = .mustHave
var contactOptions: Contact = [.name, .phone, .address]
Using an OptionSet:
let mustHave: Contact = [ name, phone ]
var contactOptions: Contact = [.name, .phone, .address]//兩個集合中相同的元素
let intersection = contactOptions.intersection(mustHave)
print(intersection) //Contact(rawValue: 3) -> name,phone//兩個集合的所有元素
let union = contactOptions.union(mustHave)
print(union) //Contact(rawValue: 11) -> name,phone, address//兩個集合未相同的元素
let subtracting = contactOptions.subtracting(mustHave)
print(subtracting) //Contact(rawValue: 8) -> address//Bool: A 是否包含 B 元素
let contains = contactOptions.contains(mustHave)
print(contains) //true//新增/刪除元素
contactOptions.insert(.email)
contactOptions.remove(.email)
Checking:
func checking() {
if contactOptions.contains(.name) {
print("name")
} if contactOptions.contains(.mustHave) {
print("mustHave")
} if contactOptions.contains(.all) {
print("all")
}
}
- OptionSet 也可加入
CaseIterable
使用Contact.allCases
。