Swift 常量默认是惰性的吗?

Posted

技术标签:

【中文标题】Swift 常量默认是惰性的吗?【英文标题】:Are Swift constants lazy by default? 【发布时间】:2015-08-29 04:41:19 【问题描述】:

我仍然不太了解 Swift ...假设我想要一个属性来实例化用于多个子类的基类中的类,例如...

let horse = Horse();

horse 是在应用/类初始化之后或第一次访问属性时立即实例化的吗?

另一方面,使用lazy var 保证该属性仅在第一次访问时被实例化...

lazy var horse = Horse()

但是horse 不是一个常数。所以在这种情况下,如果我多次访问horse,我会创建多个horse 实例,对吧?

如果我想要两者,一个也是常量的惰性属性怎么办?

【问题讨论】:

【参考方案1】:

不完全是。假设你有一个类 Farm 并且在 Farm 里面有 horse 属性。

class Farm 
    let horse = Horse()

在这种情况下,horse 属性在类实例初始化时被初始化。如果你把它设为lazy,你也必须让它可变。

class Farm 
    lazy var horse = Horse()

在这种情况下,horse 属性在第一次访问时被初始化。稍后当再次访问它时,它会再次返回相同的实例,而不是重新初始化它。但由于它是一个可变属性,您可以为其分配一个新的 Horse 实例。为它分配新值后,它会在每次访问时返回这个新值。

编辑:如果let horse = Horse() 是在全局空间中定义的,那么它会在第一次访问时延迟创建。

【讨论】:

感谢您解决这个问题!所以没有办法创建一个惰性常量。但很高兴知道它是如何工作的。【参考方案2】:

好吧,有点晚了,但我认为您可以使用 private(set) 创建一个 lazy 属性作为常量。考虑下面的例子:

import Foundation

struct GPS: CustomStringConvertible 
    let name: String

    init(name: String) 
        self.name = name
        print("GPS Initialised")
    

    var description: String 
        return name
    


struct Car 
    private(set) lazy var gps = GPS(name: "One")

    init() 
        print("Car Initialised")
    


var someCar = Car()
print(someCar.gps) // Comment/Uncomment this to see lazy in action
//someCar.gps = GPS("Two") // This will create a compilation error
//

但是,如果您删除private(set),它(Car 中的gps 变量)将再次成为一个可以变异的变量 .

您可以在删除 private(set) 后取消注释最后一行以验证是否相同

【讨论】:

以上是关于Swift 常量默认是惰性的吗?的主要内容,如果未能解决你的问题,请参考以下文章

Swift之Optional 可选值

通过枚举方式的单例是惰性初始化的吗?

关于swift中的可选类型

swift学习第十二天:类的属性定义

22.swift属性

USN日志是默认禁用的吗?