これは、ユースケースで最もよく説明されています。各オプションに関連する値を持つOptionSet
私はロガークラスを持っています。メッセージはレベルでアウトプットに記録されます。
class Logger {
var outputs: OutputOptions
var filter: Level
func log(_ message: String, at level: Level) {
if level <= self.filter {
outputs.log(message)
}
}
}
可能出力は、optionによって定義され、(の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の利点を手放すし、私のオプションを列挙型の配列にしてください。 –