(失败)选项1:生成的属性
如果派生值是生成的属性(如下所示),则始终返回正确的值,但始终重新计算.
(失败)选项2:延迟加载的属性
如果它是一个懒惰的属性,那么计算只进行一次……永远.因此,一旦结构发生变异,派生值就会出错,并且不会重新计算.此外,如果我从结构中分配一个常量值,我无法访问该属性.
在Swift 1.2中是否有任何可能的解决方案或者我需要提交雷达吗?
struct Struct { var value: Int // Option 1: Generated property var derivedValue: Int { println("Doing expensive calculation") return self.value * 2 } // Option 2: Lazy property lazy var derivedValue: Int = { println("Doing expensive calculation") return self.value * 2 }() init(value: Int) { self.value = value } mutating func mutate() { value = random() }}var test = Struct(value: 2)test.derivedValuetest.derivedValue // If not lazy,expensive calculation is done again heretest.mutate()test.derivedValue // If lazy,this has wrong valuelet test2 = testtest2.derivedValue // Compiler error if using lazy implementation@H_403_12@ 使用嵌入式类可以解决变异结构的限制.这允许您使用按值类型,该类型在需要之前不会运行昂贵的计算,但仍会记住之后的结果.下面的示例数字结构以一种与您描述的方式相似的方式计算并记住其方形属性.数学本身效率低得离谱,但这是解释解决方案的简单方法.
struct Number { // Store a cache in a nested class. // The struct only contains a reference to the class,not the class itself,// so the struct cannot prevent the class from mutating. private class Cache { var square: Int? var multiples: [Int: Int] = [:] } private var cache = Cache() // Empty the cache whenever the struct mutates. var value: Int { willSet { cache = Cache() } } // Prevent Swift from generating an unwanted default initializer. // (i.e. init(cache: Number.Cache,value: Int)) init(value: Int) { self.value = value } var square: Int { // If the computed variable has been cached... if let result = cache.square { // ...return it. print("I’m glad I don’t have to do that again.") return result } else { // Otherwise perform the expensive calculation... print("This is taking forever!") var result = 0 for var i = 1; i <= value; ++i { result += value } // ...store the result to the cache... cache.square = result // ...and return it. return result } } // A more complex example that caches the varying results // of performing an expensive operation on an input parameter. func multiple(coefficIEnt: Int) -> Int { if let result = cache.multiples[coefficIEnt] { return result } else { var result = 0 for var i = 1; i <= coefficIEnt; ++i { result += value } cache.multiples[coefficIEnt] = result return result } }}@H_403_12@这就是它的表现:
// The expensive calculation only happens once...var number = Number(value: 1000)let a = number.square // “This is taking forever!”let b = number.square // “I’m glad I don’t have to do that again.”let c = number.square // “I’m glad I don’t have to do that again.”// Unless there has been a mutation since last time.number.value = 10000let d = number.square // “This is taking forever!”let e = number.square // “I’m glad I don’t have to do that again.”// The cache even persists across copIEs...var anotherNumber = numberlet f = anotherNumber.square // “I’m glad I don’t have to do that again.”// ... until they mutate.anotherNumber.value = 100let g = anotherNumber.square // “This is taking forever!”@H_403_12@作为一个更现实的例子,我在日期结构上使用了这种技术,以确保在日历系统之间进行转换的非平凡计算尽可能少地运行.
总结以上是内存溢出为你收集整理的如何在Swift中的变异结构上正确创建一个延迟派生属性?全部内容,希望文章能够帮你解决如何在Swift中的变异结构上正确创建一个延迟派生属性?所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)