【发布时间】:2016-06-30 18:57:50
【问题描述】:
我正在学习 Swift,但在我的一个模型类中遇到了问题。 我想要做的是拥有一个延迟加载的属性,当它基于的数据发生变化时,它可以“失效”。 (类似这样:https://stackoverflow.com/a/25954243/2382892)
我现在拥有的是这样的:
class DataSet {
var entries: [Entry]
var average: Double? {
return self.entries.average
}
}
Array<Entry>.average 计算 Entry 属性的平均值,但如果数组为空,返回 nil。
由于这个平均值的计算成本可能很高,我想懒惰地这样做并存储一个缓存值,仅在必要时重新计算(当DataSet.entries 已修改)。
现在,跟随this answer,我应该这样做:
class DataSet {
var entries: [Entry]
var _average: Double?
var average: Double? {
if _average == nil {
_average = self.entries.average
}
return _average
}
}
但是,我在处理 要重新计算平均值 以及 数组为空 并且没有有意义的平均值返回的情况时遇到了问题。
因为我知道平均值总是正数,我可以使用 默认值(例如 -1.0)来表示缓存不再有效,nil 表示有没有条目,反之亦然(nil 表示必须再次计算平均值;-1.0 表示没有条目)。
然而,这似乎并不优雅,或者是实现这种行为的“Swift 方式”(或者确实如此?)。
我该怎么办?
【问题讨论】:
-
恐怕最佳实践问题不适合 Stack Overflow,因为答案只能基于意见,而不是事实。
-
你可以使用双选项
-
顺便说一下,在上面的示例中,您声明了
var average: Double { ... }的DataSet计算属性,但我假设如果没有Entry对象,entries.average将返回nil。所以我认为声明应该是var average: Double? { ... }。 -
从实践的角度来看,几乎在所有情况下,空数组的平均值 0.0 比
nil更合适。在过去的 Objective-C 时代,我们习惯于将nil视为不在乎 ;-) -
@vadian - 我不同意。
nil表示没有价值,并且具有永远不会被误认为是真实计算值的优点。您只是在使用另一个魔法值(更糟糕的是,它与潜在的有效值无法区分)。使用0并不比他最初的-1方法好。此外,他明确告诉我们“Array<Entry>.average计算Entry属性的平均值,但如果数组为空则返回nil”(这是正确的方法,恕我直言)。
标签: swift lazy-loading lazy-evaluation