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)

开始

See the feature proposal.