Swift 属性基本使用

属性:将值与特定的类、结构体或枚举关联
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)
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值