gpt4 book ai didi

swift - 带有反向选项的 OptionSet

转载 作者:搜寻专家 更新时间:2023-10-31 22:37:14 25 4
gpt4 key购买 nike

假设我有一组选项可以传递给某些进程,例如

struct Options: OptionSet {
let rawValue: Int

static let floogled = Options(rawValue: 1 << 0)
static let jibjabbed = Options(rawValue: 1 << 1)
}

这些被传递给一些函数,例如 foo(options: .floogled)bar(options: .jibjabbed)

现在,通常当我调用这些函数时,目的是启用所有选项。所以我可以用默认值定义函数,例如

func foo(options: Options = [.floogled, .jibjabbed]) {
...
}

等等,然后调用foo()。到目前为止一切顺利。

但是,在特殊情况下,我不想在启用所有选项的情况下调用这些函数,如果我可以指定哪些选项启用,使用起来会更加直观,而不是比哪些选项保持启用状态。例如,我宁愿调用 foo(options: .notFloogled) 而不是 foo(options: .jibjabbed)

我可以想到两种方法来做到这一点。第一种方式是改变选项集的定义,使其成员被负定义;换句话说

struct OptionsAlternative: OptionSet {
let rawValue: Int

static let notFloogled = Options(rawValue: 1 << 0)
static let notJibjabbed = Options(rawValue: 1 << 1)
}

然后将定义函数,默认情况下不禁用任何选项;即

func foo(options: OptionsAlternative = []) {
...
}

对于默认行为,我可以将其称为 foo(),或者当我需要禁用特定选项时,将其称为 foo(options: .notFloogled)。但是,我不想这样做,因为它会使功能的实现变得不直观。我将不得不以双重否定的方式实现将选项考虑在内的部分;比较一下这是多么笨拙:

if !options.contains(.notFloogled) {
// Floogling is enabled. Floogle the foo.
...
}

相对于

if options.contains(.floogled) {
// Floogling is enabled. Floogle the foo.
...
}

第二种方法是包括成员以指示存在选项,如在原始解决方案中一样,以及便利成员以指示不存在选项。即

extension Options {
/// Not floogled; only jibjabbed.
static let notFloogled: Options = [.jibjabbed]

/// Not jibjabbed; only floogled.
static let notJibjabbed: Options = [.floogled]
}

但是,如果我想禁用多个选项(这可以说是首先使用选项集的主要原因),这将不起作用。例如,如果我现在调用 foo(options: [.notFloogled, .notJibjabbed]),我会得到一个启用了 both floogling 和 jibjabbing 的选项集,而不是 都不是

是否有另一种方法可以实现我想要实现的目标,同时使实现和使用尽可能直观?

最佳答案

OptionSet 是一个集合。它有一个代数(SetAlgebra)。所以你不需要“倒置选项”; 反转。要反转,只需从“所有”案例中减去你自己。

为了说明(使用 Apple 自己的 OptionSet 示例):

struct ShippingOptions: OptionSet {
let rawValue: Int
static let nextDay = ShippingOptions(rawValue: 1 << 0)
static let secondDay = ShippingOptions(rawValue: 1 << 1)
static let priority = ShippingOptions(rawValue: 1 << 2)
static let standard = ShippingOptions(rawValue: 1 << 3)
// include common combinations, including an all case
static let express: ShippingOptions = [.nextDay, .secondDay]
static let all: ShippingOptions = [.express, .priority, .standard]
}

// now form the desired options using subtractions
let negatives : ShippingOptions = [.standard] // the ones you _don't_ want
let opts = ShippingOptions.all.subtracting(negatives) // subtract them from "all"!
// and pass `opts`

关于swift - 带有反向选项的 OptionSet,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54688627/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com