<aside> 🎨 计算属性可以用于结构体、类和枚举,存储属性只能用于结构体和类。

</aside>

<aside> 👜 属性不仅可以与实例关联,也可与类型本身关联,这样的属性叫做类型属性。

</aside>

<aside> 🍄 属性观察器可以添加在存储属性上,也可以添加到从父类继承的属性上。

</aside>

<aside> 💍 也可以使用属性包装器复用多个属性的 gettersetter 中的代码。

</aside>

存储属性

常量结构体实例的存储属性

如果创建了一个结构体实例并将其赋值给一个常量,则无法修改实例的任何存储属性,即使属性声明为变量也不行。

懒加载存储属性

<aside> 🥬 懒加载的存储属性必须是一个变量,因为任何常量属性必须在实例初始化时就被赋值,而懒加载的存储属性在实例初始化完成后仍然可为空。

</aside>

<aside> 🧀 如果一个被标记为 lazy 的属性在没有初始化时就同时被多个线程访问,则无法保证该属性只会被初始化一次。

</aside>

class DataImporter {
    /*
    DataImporter 是一个负责将外部文件中的数据导入的类。
    这个类的初始化会消耗不少时间。
    */
    var fileName = "data.txt"
    // 这里会提供数据导入功能
}

class DataManager {
    lazy var importer = DataImporter()
    var data: [String] = []
    // 这里会提供数据管理功能
}

let manager = DataManager()
manager.data.append("Some data")
manager.data.append("Some more data")
// DataImporter 实例的 importer 属性还没有被创建

计算属性

<aside> 🍦 必须使用 var 来声明计算属性,即使是一个只读的计算属性,因为 let 只能用来声明在实例初始化之后就不再改变的常量。

</aside>