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

问题描述 投票:2回答:1

在我的应用程序中,我使用Integers,Doubles,Floats和CGFloats来表示许多不同的值。根据我的应用程序的语义,这些值可能变为“无效”,我使用保留值表示的状态,即。即-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作为“无效”是另一种约定。

它不是更好或更糟,只是不同。 Apple在自己的API中使用“无效”值,即。即如果视图不在表格视图中,NSTableViewmethod row(for:)将返回-1。但是,我同意这个方法很好地说明了返回一个可选项会很有意义......

swift generics
1个回答
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
}

等等

© www.soinside.com 2019 - 2024. All rights reserved.