【问题标题】:Default arguments in Swift enumsSwift 枚举中的默认参数
【发布时间】:2016-03-18 08:48:49
【问题描述】:

我创建了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)

但是,我得到“不允许在 touple 类型中使用默认参数”。我希望在此处使用默认参数的原因是,此更改不会破坏或更改已使用现有实现的任何代码的行为。

您能否建议一种方法,让我可以在不更改依赖于当前 API 的代码的 API 的情况下获得新的优先级?

【问题讨论】:

  • 您不能在枚举中为关联值枚举提供默认值。您必须为每个用例定义一个或多个新枚举案例并使用它们。这不会影响您现有的代码。但就其他新病例而言,无论如何您都必须这样做

标签: swift enums default-arguments


【解决方案1】:

仅供参考: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()

【讨论】:

  • 非常感谢您,我绝对会听从您的建议。 :-)
【解决方案2】:

这现在可以从 Swift 5.1 (Xcode 11) 开始

See the feature proposal.

【讨论】:

    猜你喜欢
    • 2016-10-10
    • 1970-01-01
    • 1970-01-01
    • 2015-08-22
    • 2018-09-16
    • 1970-01-01
    • 2019-05-07
    • 2011-10-27
    • 2021-08-24
    相关资源
    最近更新 更多