在我的应用程序中,我使用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
...
它确实有效。但是,我对这种方法并不满意。你们中有谁有想法更好地表达这个吗?
为了增加一些复杂性,除了像Int
,Float
或Double
这样的简单类型之外,我还使用基于Measurement
的类型:
let length = Measurement(value: .invalid, unit: UnitLength.baseUnit())
如果您找到在解决方案中包含“无效”测量的方法,那么额外的奖励点......
谢谢你的帮助!
一些额外的想法
我知道我可以使用nil
的选项,意思是“无效”。但是,在这种情况下,你会有条件展开的额外开销......另外,使用nil
作为“无效”是另一种约定。
它不是更好或更糟,只是不同。 Apple在自己的API中使用“无效”值,即。即如果视图不在表格视图中,NSTableView
method row(for:)
将返回-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
}
等等