Swift 中的惰性只读属性
Posted
技术标签:
【中文标题】Swift 中的惰性只读属性【英文标题】:Lazy readonly property in Swift 【发布时间】:2014-11-20 18:58:32 【问题描述】:在使用 Swift 时,我尝试编写一个只读且惰性的初始化属性。我很快就写了那行代码,只是为了知道这是不允许的。
// no valid Swift code.
lazy let foo : Int = return 42 ()
您必须将惰性属性声明为var
。
这本 swift 书清楚地指出, let with lazy 是不可能的:
“您必须始终将惰性属性声明为变量(使用 var 关键字),因为在实例初始化完成之前可能无法检索其初始值。常量属性在初始化完成之前必须总是有一个值,因此不能被声明为惰性。”
假设我想在 swift 中有一个只读的惰性属性。存档的最佳方式是什么?
【问题讨论】:
【参考方案1】:如果在这种特定情况下 readonly 和 private 是您的同义词,那么您可以通过显式声明 setter 将其设为私有:
private(set) lazy var foo : Int = return 42 ()
这是不变性和惰性之间的良好折衷。
【讨论】:
私人二传手对我来说已经足够了。我也经常在 C# 中使用这种模式。 它不是一个 getter,它是一个惰性实例化闭包,但也没有必要,因为它不包含任何逻辑。这就是为什么private(set) lazy var foo = 42
会以同样的方式工作的原因。
这应该可以,但它不行:gist.github.com/4821ffb13e110dfeb027 注意:这也是一个可能的安全问题。
@Barry:我认为代码在同一个文件(或游乐场)中 - 如果是,请记住,private
不会将属性或方法设为类/结构的私有,但是文件私有,即可以从文件内的任何地方访问,但不能从任何地方访问
@cumanzor 没错,private
是把它设为私有类型,fileprivate
一样,但可以从使用它的文件中访问。【参考方案2】:
您还可以使用延迟初始化的私有后备变量:
var foo : Int return _foo
private lazy var _foo :Int = return 42 ()
【讨论】:
虽然你的答案是正确的,但我更喜欢 Antonios 的答案,因为它不会引入其他属性。 虽然接受的答案目前不起作用,但确实如此。 @Barry 接受的答案现在有效(从 Xcode 7.1 开始)【参考方案3】:可以使用计算属性和私有结构来做到这一点。静态 var 值不需要惰性关键字,因为将块的结果分配给它是隐式惰性的。
var foo: Int
struct Holder
static var value = return 42 ()
return Holder.value
【讨论】:
我认为这很聪明,在某些情况下很有用,但遗憾的是,当计算值依赖于“self”对象时它就没有用了,因为 swift 不允许内部结构关闭在外部范围内。 @Daniel 你说得很好,但是这种方法在问题的上下文中非常有效。【参考方案4】:您需要在初始化时声明该属性以使其不可变。
class Class
let foo: Int
init()
self.foo = 42
【讨论】:
以上是关于Swift 中的惰性只读属性的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Swift 中覆盖 Objective-C 的只读属性?