属性:将值与特定的类、结构体或枚举关联
1、存储属性:将常量和变量存储为实例的一部分,可用于类和结构体
①变量存储属性(var
)
②长量存储属性(let
)
2、计算属性:直接计算值,可用于类、结构体和枚举
3、类型属性:可以直接与类型本身关联
- 存储属性
struct FixedLengthRange {
var firstValue: Int
let length: Int
}
var rangeOfThreeItems = FixedLengthRange(firstValue: 0, length: 3)
print(rangeOfThreeItems.firstValue, rangeOfThreeItems.length)
rangeOfThreeItems.firstValue = 6
print(rangeOfThreeItems.firstValue, rangeOfThreeItems.length)
延时加载存储属性 当第一次被调用的时候才会计算其初始值的属性
关键字:lazy
⚠️必须将延时加载属性声明成变量,因为属性的初始值可能在实例构造完成之后才得到,而常量属性在构造过程完成之前必须拥有初始值,因此无法声明成延时加载
class 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")
print(manager.importer.fileName)
- 计算属性
不直接存储值,而是提供一个
getter
和一个可选的setter
,来间接获取和设置其他属性或变量的值
struct Point {
var x = 0.0 , y = 0.0
}
struct Size {
var width = 0.0 , height = 0.0
}
struct Rect {
var origin = Point()
var size = Size()
var center: Point {
// get {
// let centerX = origin.x + (size.width / 2)
// let centerY = origin.y + (size.height / 2)
// return Point(x: centerX, y: centerY)
// }
//简化getter 如果getter是单一表达式,gette会隐式地返回这个表达式结果
get {
Point(x: origin.x + (size.width / 2), y: origin.y + (size.height / 2))
}
// set(newCenter) {
// origin.x = newCenter.x - (size.width / 2)
// origin.y = newCenter.y - (size.height / 2)
// }
//简化setter 可以使用默认名称newValue
set {
origin.x = newValue.x - (size.width / 2)
origin.y = newValue.y - (size.height / 2)
}
}
}
var square = Rect(origin: Point(x: 0, y: 0), size: Size(width: 10, height: 10))
let initialSquareCenter = square.center
square.center = Point(x: 15, y: 15)
print("Square.origin is now at (\(square.origin.x),\(square.origin.y))")
- 只读计算属性
只有
getter
没有setter
的计算属性
总是返回一个值,可以通过点运算符访问
必须使用var
关键字定义计算属性,包括只读计算属性,因为它们的值不是固定的 可以去掉get
关键字和花括号
struct Cuboid {
var width = 0.0, height = 0.0, depth = 0.0
var volume: Double {
return width * height * depth
}
}
let fourByFiveByTwo = Cuboid(width: 4, height: 5, depth: 2)
print("THe volume of fourByFiveByTwo is \(fourByFiveByTwo.volume)")
- 属性观察器
监控和响应属性值的变化,每次属性设置值的时候都会调用属性观察器,即使新值和当前值相同的时候也不例外
willSet
:在新的值被设置之前调用,参数默认名称:newValue
didSet
:在新的值被设置之后调用,参数默认名称:oldValue
class StepCounter {
var totalSteps: Int = 0 {
willSet {
print("将totalSteps的值设置为\(newValue)")
}
didSet {
print("增加了\(totalSteps - oldValue)步")
}
}
}
let stepCounter = StepCounter()
stepCounter.totalSteps = 200
stepCounter.totalSteps = 360
stepCounter.totalSteps = 896
- 属性包装器
在管理属性和如何存储和定义属性的代码之间添加了一个分隔层
@propertyWrapper
struct TwelveOrLess {
private var number: Int
init() {
self.number = 0
}
var wrappedValue: Int {
get {
return number
}
set {
number = min(newValue, 12)
}
}
}
struct SmallRectangle {
@TwelveOrLess var height: Int
@TwelveOrLess var width: Int
}
var ractangle = SmallRectangle()
print(ractangle.height)
ractangle.height = 10
print(ractangle.height)
ractangle.height = 24
print(ractangle.height)
//设置被包装属性的初始值
@propertyWrapper
struct SmallNumber {
private var maximum: Int
private var number: Int
var wrappedValue: Int {
get {
return number
}
set {
number = min(newValue, maximum)
}
}
init() {
maximum = 12
number = 0
}
init(wrappedValue: Int) {
maximum = 12
number = min(wrappedValue, maximum)
}
init(wrappedValue: Int, maximum: Int) {
self.maximum = maximum
number = min(wrappedValue, maximum)
}
}
struct ZeroRectangle {
@SmallNumber var height: Int
@SmallNumber var width: Int
}
var zeroRectangle = ZeroRectangle()
print(zeroRectangle.height,zeroRectangle.width)
struct UnitRectangle {
@SmallNumber var height: Int = 1
@SmallNumber var width: Int = 1
}
var unitRectangle = UnitRectangle()
print(unitRectangle.height,unitRectangle.width)
struct NarrowRectangle {
@SmallNumber(wrappedValue: 2, maximum: 5) var height: Int
@SmallNumber(wrappedValue: 3, maximum: 4) var width: Int
}
var narrowRectangle = NarrowRectangle()
print(narrowRectangle.height,narrowRectangle.width)
narrowRectangle.height = 100
narrowRectangle.width = 100
print(narrowRectangle.height,narrowRectangle.width)
struct MixedRectangle {
@SmallNumber var height: Int = 1
@SmallNumber(maximum: 9) var width: Int = 2
}
var mixedRectangle = MixedRectangle()
print(mixedRectangle.height,mixedRectangle.width)
mixedRectangle.height = 20
print(mixedRectangle.height,mixedRectangle.width)
- 从属性包装器中呈现一个值
通过定义被呈现值暴露出其他功能
@propertyWrapper
struct MySmallNumber {
private var number: Int
var projectedValue: Bool
init() {
self.number = 0
self.projectedValue = false
}
var wrappedValue: Int {
get {
return number
}
set {
if newValue > 12 {
number = 12
projectedValue = true
} else {
number = newValue
projectedValue = false
}
}
}
}
struct SomeStructTrue {
@MySmallNumber var someNumber: Int
}
var someStructTrue = SomeStructTrue()
someStructTrue.someNumber = 4
print(someStructTrue.$someNumber)
someStructTrue.someNumber = 55
print(someStructTrue.$someNumber)
enum MySize {
case small, large
}
struct SizedRectangle {
@MySmallNumber var height: Int
@MySmallNumber var width:Int
mutating func resize(to size: MySize) -> Bool {
switch size {
case .small:
height = 10
width = 20
case .large:
height = 100
width = 200
}
return $height || $width
}
}
var sizedRectangle = SizedRectangle()
sizedRectangle.resize(to: MySize.small)
print(sizedRectangle.$height,sizedRectangle.$width)