结构体
struct
swift
// 定义Human结构体,遵守Equatable协议以支持==比较
struct Human: Equatable {
// 静态属性:用于统计当前创建的Human实例总数(全局共享)
static var population = 0
// 存储属性:姓名(外部可读写)
var name: String
// 存储属性:年龄(private(set)表示内部可修改,外部仅可读取),默认值0
private(set) var age = 0
// 存储属性:身高(单位可视为cm),默认值50
var height = 50
// 初始化方法1:仅传入姓名,年龄和身高使用默认值
// 创建实例时,将全局人口数+1
init(_ name: String) {
self.name = name
Human.population += 1
}
// 初始化方法2:传入姓名、年龄、身高的完整参数
// 创建实例时,将全局人口数+1
init(_ name: String, age: Int, height: Int) {
self.name = name
self.age = age
self.height = height
Human.population += 1
}
// 实现Equatable协议的==方法:自定义相等性判断逻辑
// 此处规则:两个Human实例的name相同即视为相等(忽略age和height)
static func == (lhs: Self, rhs: Self) -> Bool {
lhs.name == rhs.name
}
// 实例方法:处理过生日逻辑
// mutating关键字:允许值类型(结构体)内部修改自身存储属性
mutating func 过生日() {
age += 1 // 年龄+1
print("happy birthday") // 打印生日祝福
// 若年龄小于20(青少年阶段),身高随机增加0-5之间的整数
if age < 20 {
height += (0...5).randomElement()!
}
}
}
// 创建第一个Human实例:使用初始化方法1,name为"Jame",age=0,height=50
// 此时population变为1
var person = Human("Jame")
// 创建第二个Human实例:使用初始化方法2,name为"Cindy",age=15,height=160
// 此时population变为2
var person2 = Human("Cindy", age: 15, height: 160)
// 比较person和person2:name分别为"Jame"和"Cindy",不相等,输出false
print(person == person2)
// 修改person2的name为"Jame",与person的name一致
person2.name = "Jame"
// 再次比较:name均为"Jame",相等,输出true
print(person == person2)
// 调用person的过生日方法:age从0变为1,因age<20,height随机增加0-5
person.过生日()
// 打印person实例:输出其当前属性值(格式为结构体默认调试描述)
print(person)
print(person2)
//打印人口
print("总人口是:",Human.population)
计算属性
swift
// 导入Foundation框架,提供基础数据类型(如Double)和数学函数(如sqrt平方根)支持
import Foundation
// 定义一个"方形"结构体,用于描述方形的特征和行为
struct 方形{
// 存储属性:边长(Double类型,直接存储具体数值,是结构体的核心数据)
var 边长: Double
// 计算属性:面积(不直接存储值,通过计算得到或反向修改其他属性)
var 面积: Double {
// set方法:当给"面积"赋值时触发,用于反向计算并修改"边长"
// (area)是自定义参数名(替代默认的newValue),接收赋值时的新面积值
set(area){
print(">>>正在修改边长") // 打印日志,标记set方法被调用
边长 = sqrt(area) // 通过新面积值反推边长:边长 = 面积的平方根(数学公式:面积=边长² → 边长=√面积)
}
// get方法:当获取"面积"值时触发,用于计算当前面积
get {
print(">>>正在计算面积") // 打印日志,标记get方法被调用
return 边长 * 边长 // 通过边长计算面积(数学公式:面积=边长×边长)
}
}
}
// 1. 创建方形实例:
// 结构体自动生成"成员初始化器",需传入存储属性"边长"的值(这里传入10,自动转为Double类型10.0)
// 用var声明变量square,后续可修改其属性(如边长)
var square = 方形(边长: 10)
// 2. 打印square的面积:
// 访问"面积"属性时,触发get方法,计算并返回当前面积(10×10=100)
// 执行后会先打印">>>正在计算面积",再输出面积值100.0
print(square.面积)
// 3. 修改square的边长为4:
// 直接修改存储属性"边长"的值(此时不触发计算属性的方法)
square.边长 = 4
// 4. 再次打印面积:
// 再次访问"面积",触发get方法,重新计算面积(4×4=16)
// 执行后先打印">>>正在计算面积",再输出16.0
print(square.面积)
// 5. 给"面积"赋值64:
// 给计算属性"面积"赋值时,触发set方法,用新面积值64反推边长(√64=8)
// 执行后会打印">>>正在修改边长",此时square的"边长"被更新为8.0
square.面积 = 64
// 6. 打印square实例:
// 输出结构体实例的当前状态,会显示存储属性"边长"的值(此时已被set方法修改为8.0)
// 输出结果类似:方形(边长: 8.0)
print(square)
属性观察者和lazy属性
swift
// 导入Foundation框架,提供基础数据类型支持(如Double)和系统功能
import Foundation
// 定义一个"方形"结构体,用于描述方形的边长和面积属性及关联逻辑
struct 方形{
// 存储属性:边长(Double类型),带有属性观察者(监控边长的修改行为)
var 边长: Double{
// willSet:属性值即将被修改时触发(修改前执行)
willSet{
// 打印当前边长和即将修改的新值
// newValue:系统自动提供的变量,代表即将赋给"边长"的新值
print(">>>即将把边长 \(边长) 改成 \(newValue)")
}
// didSet:属性值已经被修改后触发(修改后执行)
didSet{
// 用修改后的新边长重新计算面积并更新
面积 = 边长 * 边长
// 打印修改前的旧边长和修改后的新边长
// oldValue:系统自动提供的变量,代表"边长"修改前的旧值
print(">>>已经把边长 \(oldValue) 改成了 \(边长)")
}
}
// 懒加载+访问控制的存储属性:面积(Double类型)
// lazy:懒加载,第一次访问"面积"时才执行闭包计算值,之后直接复用(避免初始不必要的计算)
// private(set):访问控制,外部只能读取"面积",不能修改(内部可通过didSet等逻辑修改)
// = { ... }():闭包表达式,作为"面积"的初始化逻辑(第一次访问时执行)
lazy private(set) var 面积: Double = {
print(">>> 现在计算面积并重新赋值") // 标记第一次计算面积的行为
return 边长 * 边长 // 用当前边长计算初始面积
}()
}
// 创建"方形"结构体实例,通过自动生成的成员初始化器给"边长"赋值10(自动转为Double类型10.0)
var square = 方形(边长: 10)
// 第一次访问"面积"属性,触发懒加载逻辑:执行面积的闭包初始化,计算并获取面积值
// 执行后会先打印闭包内的日志,再输出面积结果
print(square.面积)
// 修改"边长"的值为20,触发"边长"的属性观察者:先执行willSet,再修改值,最后执行didSet
square.边长 = 20
// 打印当前"方形"实例的状态,输出存储属性"边长"和"面积"的当前值
print(square)