Swift 枚举中的默认参数
Default arguments in Swift enums
我制作了 SnapOperationQueue,这是一个带有一些我喜欢的扩展的操作队列。其中之一是重新确定操作组的优先级。添加具有以下四个优先级之一的操作 (SnapOperationQueuePriority):
case Highest
case High
case Normal
case Low
在当前的实现中,.Low 和 .Highest 不会改变,但 .High 和 .Normal 会改变。
我想更改此设置,以便我可以设置优先级的上限和下限。也就是说,我可以说我们现在最好做的这个操作 (.Low) 可能会变得非常重要 (.High),即当预缓存图像并且屏幕上突然需要该图像时。这些阈值还应该能够说明某些操作,即使在重新设置优先级的组中,也不会被重新设置为低于某些操作的优先级,即登录操作 (.Highest) 应该保持 .Highest
为此,我想像这样修改我的枚举:
case Highest(lowerThreshold: SnapOperationQueuePriority = .Highest)
case High(lowerThreshold: SnapOperationQueuePriority = .Low, higherThreshold: SnapOperationQueuePriority = .High)
case Normal(lowerThreshold: SnapOperationQueuePriority = .Low, higherThreshold: SnapOperationQueuePriority = .High)
case Low(higherThreshold: SnapOperationQueuePriority = .Low)
然而,我得到 "Default argument not permitted in a touple type"。我想在此处使用默认参数的原因是,此更改不会破坏或更改任何已在使用现有实现的代码的行为。
您能否建议一种方法,使我可以获得新的优先级,但不更改依赖于当前 API 的代码的 API?
仅供参考:Swift 5.1 之后现在允许使用默认参数值。此答案仅适用于之前的 Swift 版本。
这是一个棘手的问题,因为您不能有默认值,不能有存储的属性,也不能在枚举中重复案例名称。我能想到的最好的事情是创建一个 init() 和一些 semi-private 案例。
enum SnapOperationQueuePriority {
case Highest, High, Low, Default
}
enum SnapOperationQueue {
case Highest, High, Normal, Low
case _Highest(lowerThreshold: SnapOperationQueuePriority)
case _High(lowerThreshold: SnapOperationQueuePriority, higherThreshold: SnapOperationQueuePriority)
case _Normal(lowerThreshold: SnapOperationQueuePriority, higherThreshold: SnapOperationQueuePriority)
case _Low(higherThreshold: SnapOperationQueuePriority)
init(queue:SnapOperationQueue, lowerThreshold:SnapOperationQueuePriority = .Default, higherThreshold:SnapOperationQueuePriority = .Default) {
switch queue {
case .Highest:
self = ._Highest(lowerThreshold: lowerThreshold == .Default ? .Highest : lowerThreshold)
case .High:
self = ._High(lowerThreshold: lowerThreshold == .Default ? .Low : lowerThreshold, higherThreshold: higherThreshold == .Default ? .High : higherThreshold)
case .Normal:
self = ._Normal(lowerThreshold: lowerThreshold == .Default ? .Low : lowerThreshold, higherThreshold: higherThreshold == .Default ? .High : higherThreshold)
case Low:
self = ._Low(higherThreshold: higherThreshold == .Default ? .Low : higherThreshold)
default:
self = queue
}
}
}
SnapOperationQueue.Normal
SnapOperationQueue(queue: .Normal)
SnapOperationQueue(queue: .High, lowerThreshold: .High, higherThreshold: .Highest)
这使旧的实现保持有效并捕获使用 init 创建的新实现。此外,您可以将这样的方法添加到枚举中:
func queue() -> SnapOperationQueue {
switch self {
case .Highest:
return SnapOperationQueue(queue: .Highest)
case .High:
return SnapOperationQueue(queue: .High)
case .Normal:
return SnapOperationQueue(queue: .Normal)
case Low:
return SnapOperationQueue(queue: .Low)
default:
return self
}
}
以便您可以将旧类型的枚举案例转换为新的,例如SnapOperationQueue.Normal.queue()
现在可以从 Swift 5.1 (Xcode 11)
开始
我制作了 SnapOperationQueue,这是一个带有一些我喜欢的扩展的操作队列。其中之一是重新确定操作组的优先级。添加具有以下四个优先级之一的操作 (SnapOperationQueuePriority):
case Highest
case High
case Normal
case Low
在当前的实现中,.Low 和 .Highest 不会改变,但 .High 和 .Normal 会改变。
我想更改此设置,以便我可以设置优先级的上限和下限。也就是说,我可以说我们现在最好做的这个操作 (.Low) 可能会变得非常重要 (.High),即当预缓存图像并且屏幕上突然需要该图像时。这些阈值还应该能够说明某些操作,即使在重新设置优先级的组中,也不会被重新设置为低于某些操作的优先级,即登录操作 (.Highest) 应该保持 .Highest
为此,我想像这样修改我的枚举:
case Highest(lowerThreshold: SnapOperationQueuePriority = .Highest)
case High(lowerThreshold: SnapOperationQueuePriority = .Low, higherThreshold: SnapOperationQueuePriority = .High)
case Normal(lowerThreshold: SnapOperationQueuePriority = .Low, higherThreshold: SnapOperationQueuePriority = .High)
case Low(higherThreshold: SnapOperationQueuePriority = .Low)
然而,我得到 "Default argument not permitted in a touple type"。我想在此处使用默认参数的原因是,此更改不会破坏或更改任何已在使用现有实现的代码的行为。
您能否建议一种方法,使我可以获得新的优先级,但不更改依赖于当前 API 的代码的 API?
仅供参考:Swift 5.1 之后现在允许使用默认参数值。此答案仅适用于之前的 Swift 版本。
这是一个棘手的问题,因为您不能有默认值,不能有存储的属性,也不能在枚举中重复案例名称。我能想到的最好的事情是创建一个 init() 和一些 semi-private 案例。
enum SnapOperationQueuePriority {
case Highest, High, Low, Default
}
enum SnapOperationQueue {
case Highest, High, Normal, Low
case _Highest(lowerThreshold: SnapOperationQueuePriority)
case _High(lowerThreshold: SnapOperationQueuePriority, higherThreshold: SnapOperationQueuePriority)
case _Normal(lowerThreshold: SnapOperationQueuePriority, higherThreshold: SnapOperationQueuePriority)
case _Low(higherThreshold: SnapOperationQueuePriority)
init(queue:SnapOperationQueue, lowerThreshold:SnapOperationQueuePriority = .Default, higherThreshold:SnapOperationQueuePriority = .Default) {
switch queue {
case .Highest:
self = ._Highest(lowerThreshold: lowerThreshold == .Default ? .Highest : lowerThreshold)
case .High:
self = ._High(lowerThreshold: lowerThreshold == .Default ? .Low : lowerThreshold, higherThreshold: higherThreshold == .Default ? .High : higherThreshold)
case .Normal:
self = ._Normal(lowerThreshold: lowerThreshold == .Default ? .Low : lowerThreshold, higherThreshold: higherThreshold == .Default ? .High : higherThreshold)
case Low:
self = ._Low(higherThreshold: higherThreshold == .Default ? .Low : higherThreshold)
default:
self = queue
}
}
}
SnapOperationQueue.Normal
SnapOperationQueue(queue: .Normal)
SnapOperationQueue(queue: .High, lowerThreshold: .High, higherThreshold: .Highest)
这使旧的实现保持有效并捕获使用 init 创建的新实现。此外,您可以将这样的方法添加到枚举中:
func queue() -> SnapOperationQueue {
switch self {
case .Highest:
return SnapOperationQueue(queue: .Highest)
case .High:
return SnapOperationQueue(queue: .High)
case .Normal:
return SnapOperationQueue(queue: .Normal)
case Low:
return SnapOperationQueue(queue: .Low)
default:
return self
}
}
以便您可以将旧类型的枚举案例转换为新的,例如SnapOperationQueue.Normal.queue()
现在可以从 Swift 5.1 (Xcode 11)
开始