如何为不同类型定义通用的“无效”值

时间:2018-09-11 09:39:18

标签: swift generics

在我的应用中,我使用整数,双精度数,浮点数和CGFloats来表示许多不同的值。根据我的应用的语义,这些值可能会变为“无效”,这是我使用保留值表示的一种状态,即e。 -1。使它在代码中可用的最简单方法是:

anIntVariable = -1
aFloatVariable = -1
aDoubleVariable = -1.0
...

为了摆脱这种惯例驱动的方法并提高可读性和适应性,我定义了许多扩展:

extension Int {
    static var invalid = -1
}
extension Float {
    static var invalid = -1.0
}
extension Double {
    static var invalid = -1.0
}
...

因此上面的代码现在显示为:

anIntVariable = .invalid
aFloatVariable = .invalid
aDoubleVariable = .invalid
...

它确实起作用。但是,我对这种方法并不满意。你们当中有人想出一种更好的表达方式吗?

为了增加一些复杂性,除了像IntFloatDouble这样的简单类型之外,我还使用基于Measurement的类型,如下所示:

let length = Measurement(value: .invalid, unit: UnitLength.baseUnit())

如果您还找到一种在解决方案中包括“无效”测量值的方法,则会获得额外的奖励积分...

感谢您的帮助!


一些其他想法

我知道我可以使用nil表示“无效”的可选选项。但是,在这种情况下,使用条件解包会产生额外的开销...另外,将nil用作“无效”是另一种约定。

这并没有好坏,只是有所不同。苹果在自己的API中使用“无效”值,即e。如果视图不在表视图中,则NSTableView方法row(for:)将返回-1。但是,我同意,这种方法可以完美地说明,返回一个可选内容很有意义...

1 个答案:

答案 0 :(得分:1)

我会为此使用可选的。

如果您希望缺乏价值和无效价值成为应用程序中的不同状态,我建议为您的价值创造包装材料:

enum Validatable<T> {
   case valid(T)
   case invalid
}

并像这样使用它:

let validValue : Validatable<Int> = .valid(5)
let invalidValue : Validatable<Int> = .invalid

var validOptionalDouble : Validatable<Double?> = .valid(nil)
validOptionalDouble = .valid(5.0)

let measurement : Validatable<Measurement> = .invalid

然后您可以通过打开该枚举来访问值,以检查其值,如下所示:

switch validatableValue {
case .valid(let value):
    //do something with value
case .invalid:
    //handle invalid state
}

if case .valid(let value) = validatableValue {
    //handle valid state
}