Properties 程式範例 — Apple’s The Swift Programming Language
Stored Properties
儲存資料的 property。
struct FixedLengthRange { var firstValue: Int let length: Int}var rangeOfThreeItems = FixedLengthRange(firstValue: 0, length: 3)rangeOfThreeItems.firstValue = 6
Stored Properties of Constant Structure Instances
struct 是 value type,當 rangeOfFourItems 宣告為常數時,不能修改它的 property。
let rangeOfFourItems = FixedLengthRange(firstValue: 0, length: 4)
// this range represents integer values 0, 1, 2, and 3
rangeOfFourItems.firstValue = 6
// this will report an error, even though firstValue is a variable property
Lazy Stored Properties
加了 lazy 的 property 會等第一次存取時才設定內容。
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)
Computed Properties
透過 getter & setter 程式計算存取的 property。
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) } set(newCenter) { origin.x = newCenter.x - (size.width / 2) origin.y = newCenter.y - (size.height / 2) } }}var square = Rect(origin: Point(x: 0.0, y: 0.0),size: Size(width: 10.0, height: 10.0))let initialSquareCenter = square.centersquare.center = Point(x: 15.0, y: 15.0)print("square.origin is now at (\(square.origin.x), \(square.origin.y))")// Prints "square.origin is now at (10.0, 10.0)"
Shorthand Setter Declaration
以自動生成的 newValue 當 setter 設定的內容。
struct AlternativeRect { 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) } set { origin.x = newValue.x - (size.width / 2) origin.y = newValue.y - (size.height / 2) } }}
Read-Only Computed Properties
只能讀取,不能修改的 property。
struct Cuboid { var width = 0.0, height = 0.0, depth = 0.0 var volume: Double { return width * height * depth }}let fourByFiveByTwo = Cuboid(width: 4.0, height: 5.0, depth: 2.0)print("the volume of fourByFiveByTwo is \(fourByFiveByTwo.volume)")// Prints "the volume of fourByFiveByTwo is 40.0"
Property Observers
利用 willSet & didSet 定義 property 內容被設定時觸發的程式。
class StepCounter { var totalSteps: Int = 0 { willSet(newTotalSteps) { print("About to set totalSteps to \(newTotalSteps)") } didSet { if totalSteps > oldValue { print("Added \(totalSteps - oldValue) steps") } } }}let stepCounter = StepCounter()stepCounter.totalSteps = 200// About to set totalSteps to 200// Added 200 stepsstepCounter.totalSteps = 360// About to set totalSteps to 360// Added 160 stepsstepCounter.totalSteps = 896// About to set totalSteps to 896// Added 536 steps
Type Property Syntax
型別的 property
struct SomeStructure { static var storedTypeProperty = "Some value." static var computedTypeProperty: Int { return 1 }}enum SomeEnumeration { static var storedTypeProperty = "Some value." static var computedTypeProperty: Int { return 6 }}class SomeClass { static var storedTypeProperty = "Some value." static var computedTypeProperty: Int { return 27 } class var overrideableComputedTypeProperty: Int { return 107 }}
Querying and Setting Type Properties
print(SomeStructure.storedTypeProperty)// Prints "Some value."SomeStructure.storedTypeProperty = "Another value."print(SomeStructure.storedTypeProperty)// Prints "Another value."print(SomeEnumeration.computedTypeProperty)// Prints "6"print(SomeClass.computedTypeProperty)// Prints "27"
AudioChannel 範例
struct AudioChannel { static let thresholdLevel = 10 static var maxInputLevelForAllChannels = 0 var currentLevel: Int = 0 { didSet { if currentLevel > AudioChannel.thresholdLevel { currentLevel = AudioChannel.thresholdLevel } if currentLevel > AudioChannel.maxInputLevelForAllChannels { AudioChannel.maxInputLevelForAllChannels = currentLevel } } }}
var leftChannel = AudioChannel()var rightChannel = AudioChannel()leftChannel.currentLevel = 7print(leftChannel.currentLevel)// Prints "7"print(AudioChannel.maxInputLevelForAllChannels)// Prints "7"rightChannel.currentLevel = 11print(rightChannel.currentLevel)// Prints "10"print(AudioChannel.maxInputLevelForAllChannels)// Prints "10"