Swift中的Lazy只读属性

Swift中的Lazy只读属性,swift,Swift,在玩Swift的时候,我试着写一个只读和惰性的初始化属性。我很快就写了那行代码,只是为了知道这是不允许的 // no valid Swift code. lazy let foo : Int = { return 42 }() 您必须将惰性属性声明为var。 swift手册明确指出,让懒惰成为可能是有充分理由的: 必须始终将惰性属性声明为变量(使用var关键字),因为在实例初始化完成之前可能无法检索其初始值。常量属性必须在初始化完成之前始终具有值,因此不能声明为惰性 假设我想在swift中拥有

在玩Swift的时候,我试着写一个只读和惰性的初始化属性。我很快就写了那行代码,只是为了知道这是不允许的

// no valid Swift code.
lazy let foo : Int = { return 42 }()
您必须将惰性属性声明为
var
。 swift手册明确指出,让懒惰成为可能是有充分理由的:

必须始终将惰性属性声明为变量(使用var关键字),因为在实例初始化完成之前可能无法检索其初始值。常量属性必须在初始化完成之前始终具有值,因此不能声明为惰性


假设我想在swift中拥有一个只读的lazy属性。归档该文件的最佳方式是什么?

如果在这种特定情况下readonly和private是您的同义词,那么您可以通过显式声明将setter设置为private:

private(set) lazy var foo : Int = { return 42 }()

这是不变性和惰性之间的一个很好的折衷。

您还可以使用一个惰性初始化的私有支持变量:

var foo : Int { return _foo }
private lazy var _foo :Int = { return 42 }()

这可以通过计算属性和私有结构来实现。静态var值上不需要lazy关键字,因为将块的结果分配给它是隐式的lazy

var foo: Int {
    struct Holder {
        static var value = { return 42 }()
    }
    return Holder.value
}

一等兵对我来说就足够了。我也经常在C#中使用这种模式,它不是getter,它是一个惰性的实例化闭包,但也不是必需的,因为它不包含任何逻辑。这就是为什么
private(set)lazy var foo=42
将以同样的方式工作。这应该可以工作,但它不会:注意:这也是一个可能的安全问题。@Barry:我假设代码在同一个文件(或游乐场)中-如果是,请记住,
private
不会使属性或方法成为类/结构的私有属性或方法,但对文件是私有的,即可从文件中的任何位置访问,但无法从anywhere@cumanzor没错,
private
是将其私有化为类型,
fileprivate
相同,但是可以从使用它的文件中访问。虽然您的答案是正确的,但我更喜欢Antonios answer,因为它没有引入其他属性。虽然接受的答案目前不起作用,但它确实起作用。@Barry接受的答案现在起作用了(从Xcode 7.1开始)。我认为这很聪明,在某些情况下很有用,但很遗憾,当计算值依赖于“self”对象时,这是没有用的,因为swift不允许内部结构关闭外部范围。@Daniel你说得很好,但是这种方法在问题的上下文中非常有效。