classDataImporter{ /* DataImporter is a class to import data from an external file. The class is assumed to take a nontrivial amount of time to initialize. */ var filename ="data.txt" // the DataImporter class would provide data importing functionality here }
classDataManager{ lazyvar importer =DataImporter() var data = [String]() // the DataManager class would provide data management functionality here }
let manager =DataManager() manager.data.append("Some data") manager.data.append("Some more data") // the DataImporter instance for the importer property has not yet been created
print(manager.importer.filename) // the DataImporter instance for the importer property has now been created // Prints "data.txt"
计算属性。
structPoint{ var x =0.0, y =0.0 } structSize{ var width =0.0, height =0.0 } structRect{ var origin =Point() var size =Size() var center: Point { get { let centerX = origin.x + (size.width /2) let centerY = origin.y + (size.height /2) returnPoint(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.center square.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)"
如果计算属性的 set 没有定义变量名,则使用默认的 newValue。
structAlternativeRect{ var origin =Point() var size =Size() var center: Point { get { let centerX = origin.x + (size.width /2) let centerY = origin.y + (size.height /2) returnPoint(x: centerX, y: centerY) } set { origin.x = newValue.x - (size.width /2) origin.y = newValue.y - (size.height /2) } } }
只读属性。
structCuboid{ 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"
监视属性可以使用 willSet 和 didSet 钩子。这很方便的可以在属性改变时做点什么。
classStepCounter{ 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 steps stepCounter.totalSteps =360 // About to set totalSteps to 360 // Added 160 steps stepCounter.totalSteps =896 // About to set totalSteps to 896 // Added 536 steps
structAudioChannel{ staticlet thresholdLevel =10 staticvar maxInputLevelForAllChannels =0 var currentLevel: Int=0 { didSet { if currentLevel >AudioChannel.thresholdLevel { // cap the new audio level to the threshold level currentLevel =AudioChannel.thresholdLevel } if currentLevel >AudioChannel.maxInputLevelForAllChannels { // store this as the new overall maximum input level AudioChannel.maxInputLevelForAllChannels = currentLevel } } } }
下面看看操作的例子。
var leftChannel =AudioChannel() var rightChannel =AudioChannel()
leftChannel.currentLevel =7 print(leftChannel.currentLevel) // Prints "7" print(AudioChannel.maxInputLevelForAllChannels) // Prints "7"
rightChannel.currentLevel =11 print(rightChannel.currentLevel) // Prints "10" print(AudioChannel.maxInputLevelForAllChannels) // Prints "10"
let counter =Counter() // the initial counter value is 0 counter.increment() // the counter's value is now 1 counter.increment(by: 5) // the counter's value is now 6 counter.reset() // the counter's value is now 0
structPoint{ var x =0.0, y =0.0 mutatingfuncmoveBy(xdeltaX: Double, ydeltaY: Double) { x += deltaX y += deltaY } } var somePoint =Point(x: 1.0, y: 1.0) somePoint.moveBy(x: 2.0, y: 3.0) print("The point is now at (\(somePoint.x), \(somePoint.y))") // Prints "The point is now at (3.0, 4.0)"
let fixedPoint =Point(x: 3.0, y: 3.0) fixedPoint.moveBy(x: 2.0, y: 3.0) // this will report an error
枚举类型自己处理自己。
enumTriStateSwitch{ case off, low, high mutatingfuncnext() { switchself { case .off: self= .low case .low: self= .high case .high: self= .off } } } var ovenLight =TriStateSwitch.low ovenLight.next() // ovenLight is now equal to .high ovenLight.next() // ovenLight is now equal to .off
方法同样分实例方法和类型方法。实例方法是由实例调用,类型方法需要对类型操作。通常使用 static 关键字表示,类可以使用 class 关键字修饰 func 来让子类可以覆盖它。
R:类似 Java 中的静态工具方法。
classSomeClass{ classfuncsomeTypeMethod() { // type method implementation goes here } } SomeClass.someTypeMethod()
structLevelTracker{ staticvar highestUnlockedLevel =1 var currentLevel =1