因为the behavior of lazy changed in Swift 4,我写了一些structs,它们给出了非常具体的行为,在语言版本之间永远不应该改变。我把这些放在 GitHub 上,在 the BH-1-PD 许可下:https://github.com/RougeWare/Swift-Lazy-Patterns
这是与此问题相关的问题,它为您提供了一种延迟初始化值、缓存该值并销毁它以便以后可以延迟重新初始化的方法。
请注意,这需要 Swift 5.1! 对于 Swift 4 版本,请参阅 version 1.1.1 of that repo。
this的简单用法非常直接:
@ResettableLazy
var myLazyString = "Hello, lazy!"
print(myLazyString) // Initializes, caches, and returns the value "Hello, lazy!"
print(myLazyString) // Just returns the value "Hello, lazy!"
_myLazyString.clear()
print(myLazyString) // Initializes, caches, and returns the value "Hello, lazy!"
print(myLazyString) // Just returns the value "Hello, lazy!"
myLazyString = "Overwritten"
print(myLazyString) // Just returns the value "Overwritten"
_myLazyString.clear()
print(myLazyString.wrappedValue) // Initializes, caches, and returns the value "Hello, lazy!"
这将打印:
Hello, lazy!
Hello, lazy!
Hello, lazy!
Hello, lazy!
Overwritten
Hello, lazy!
如果你有复杂的初始化逻辑,你可以将它传递给属性包装器:
func makeLazyString() -> String {
print("Initializer side-effect")
return "Hello, lazy!"
}
@ResettableLazy(initializer: makeLazyString)
var myLazyString: String
print(myLazyString) // Initializes, caches, and returns the value "Hello, lazy!"
print(myLazyString) // Just returns the value "Hello, lazy!"
_myLazyString.clear()
print(myLazyString) // Initializes, caches, and returns the value "Hello, lazy!"
print(myLazyString) // Just returns the value "Hello, lazy!"
myLazyString = "Overwritten"
print(myLazyString) // Just returns the value "Overwritten"
_myLazyString.clear()
print(myLazyString.wrappedValue) // Initializes, caches, and returns the value "Hello, lazy!"
您也可以直接使用它(代替作为属性包装器):
var myLazyString = ResettableLazy<String>() {
print("Initializer side-effect")
return "Hello, lazy!"
}
print(myLazyString.wrappedValue) // Initializes, caches, and returns the value "Hello, lazy!"
print(myLazyString.wrappedValue) // Just returns the value "Hello, lazy!"
myLazyString.clear()
print(myLazyString.wrappedValue) // Initializes, caches, and returns the value "Hello, lazy!"
print(myLazyString.wrappedValue) // Just returns the value "Hello, lazy!"
myLazyString.wrappedValue = "Overwritten"
print(myLazyString.wrappedValue) // Just returns the value "Overwritten"
_myLazyString.clear()
print(myLazyString.wrappedValue) // Initializes, caches, and returns the value "Hello, lazy!"
这些都将打印:
Initializer side-effect
Hello, lazy!
Hello, lazy!
Initializer side-effect
Hello, lazy!
Hello, lazy!
Overwritten
Initializer side-effect
Hello, lazy!
此答案已更新;它的原始解决方案不再适用于 Swift 4 及更高版本。
相反,我建议您使用上面列出的解决方案之一,或@PBosman's solution
以前,此答案取决于作为错误的行为。这个答案的旧版本、它的行为以及它为什么是一个错误都在 Swift bug SR-5172 的文本和 cmets 中进行了描述(截至 2017 年 7 月 14 日,PR #10,911 已解决),很明显,这行为从来都不是故意的。
该解决方案在那个 Swift 错误的文本中,也在 the history of this answer 中,但是因为它是一个在 Swift 3.2+ 中不起作用的漏洞利用我建议你这样做不要这样做那个。