這可能最好用一個用例來解釋。OptionSet與每個選項的關聯值
我有一個記錄類。它將消息記錄到輸出級別。
class Logger {
var outputs: OutputOptions
var filter: Level
func log(_ message: String, at level: Level) {
if level <= self.filter {
outputs.log(message)
}
}
}
可能的輸出由定義OptionSet並確定要它輸出(的NSLog,Instabug等)消息應該被記錄。 OptionSet在這裏很不錯,因爲我可以定義選擇多個輸出並輕鬆檢查在記錄時選擇哪個。
struct OutputOptions: OptionSet {
let rawValue: Int
static let console = OutputOptions(1 << 0)
static let instabug = OutputOptions(1 << 1)
func log(_ message: String) {
if self.contains(.console) {
NSLog(message)
}
// etc
}
}
水平是通過枚舉定義的,並且表示消息的水平,如錯誤,警告,信息等記錄器可以過濾掉消息高於某一水平,如果我們不感興趣得到一個冗長的輸出。記錄器的過濾器也被設置爲一個級別。
enum Level: Int {none, no logs are shown. */
case none = 0
case error = 1
case warning = 2
case info = 3
case verbose = 4
}
我想輸出選項和級別相結合以某種方式,讓我指定某些輸出可過濾消息到一定的水平,而其他輸出可以過濾到其他級別。例如,我想將詳細消息記錄到控制檯,但只有錯誤發送給Instabug。從表面上看,OptionSets看起來像可組合的枚舉,所以我的思想立即轉到相關的值。如果每個選項可以有一個相關的過濾級別,我可以設置一個記錄器的輸出是這樣的:
let logger = Loggger()
logger.outputs = [.console(filter: .verbose), .instabug(filter: .error)]
在試圖得到這個工作,我添加了一個過濾器屬性設置OutputOptions。我選擇現在這個樣子:
struct OutputOptions: OptionSet {
let rawValue: Int
var filter: Level = .info
init(rawValue: Int, filter: Level) {
self.rawValue = rawValue
self.filter = filter
}
static func console(filter: Level = .info) {
return OutputOptions(rawValue: 1 << 0, filter: filter)
}
// etc
,但我無法弄清楚如何訪問一個元素的過濾器變量log
。根據我對枚舉的經驗,我本可以期望能夠做到
func log(_ message: String, at level: Level) {
if self.contains(.console(let filter)) { // <== does not compile!
if level <= filter {
NSLog(message)
}
}
}
}
但是這並不能編譯。事實上,它看起來像filter
屬性沒有爲每個選項單獨定義,而是爲整個選項集。
SO:有沒有辦法將值與選項集中的各個選項相關聯?
有道理。也許我應該放棄OptionSet的好處,然後讓我的選項成爲一個枚舉數組。 –