斯威夫特懒惰的只读属性

MBu*_*lli 22 swift

在使用Swift玩一点时,我尝试编写一个readonly和lazy初始化属性.我很快就编写了这行代码,以了解它是不允许的.

// no valid Swift code.
lazy let foo : Int = { return 42 }()
Run Code Online (Sandbox Code Playgroud)

您必须将延迟属性声明为var.这本快速的书明确指出,懒惰是不可能有充分理由:

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

假设我想在swift中拥有一个readonly lazy属性.什么是存档的最佳方式?

Ant*_*nio 41

如果readonly和private在这种特定情况下是您的同义词,那么您可以通过显式声明它来使setter变为私有:

private(set) lazy var foo : Int = { return 42 }()
Run Code Online (Sandbox Code Playgroud)

这是不变性和懒惰之间的良好折衷.

  • 它不是一个getter,它是一个惰性的实例化闭包,但它没有必要,因为它不包含任何逻辑.这就是为什么`private(set)lazy var foo = 42`将以同样的方式工作. (4认同)
  • @Barry:我假设代码在同一个文件(或操场)中 - 如果是的话,请记住,`private`不会使属性或方法对类/结构是私有的,而是私有的文件,即可从文件内的任何地方,但无法从任何地方访问 (2认同)
  • @cumanzor,是的,“private”是使其对类型私有,“fileprivate”相同,但可以从使用它的文件内访问。 (2认同)

Dav*_*rry 6

您还可以使用懒惰初始化的私有后备变量:

var foo : Int { return _foo }
private lazy var _foo :Int = { return 42 }()
Run Code Online (Sandbox Code Playgroud)

  • 虽然你的答案是正确的,但我更喜欢Antonios的答案,因为它没有引入另一个属性. (3认同)

kev*_*vin 5

可以使用计算属性和私有结构来做到这一点。static var 值不需要使用lazy 关键字,因为将块的结果分配给它是隐式惰性的。

var foo: Int {
    struct Holder {
        static var value = { return 42 }()
    }
    return Holder.value
}
Run Code Online (Sandbox Code Playgroud)

  • 我认为这很聪明,在某些情况下很有用,但遗憾的是,当计算值依赖于“self”对象时,它没有用,因为 swift 不允许内部结构关闭外部作用域。 (2认同)