屬性在前面的枚舉,類,結構體中都已經使用過,本章介紹屬性的性質和方法
?
<col>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<code>struct</code> <code>FixedLengthRange {</code>
<code>var firstValue: Int</code>
<code>let length: Int</code>
<code>}</code>
<code>var rangeOfThreeItems = FixedLengthRange(firstValue: 0, length: 3)</code>
<code>// the range represents integer values 0, 1, and 2</code>
<code>rangeOfThreeItems.firstValue = 6</code>
<code>// the range now represents integer values 6, 7, and 8</code>
<code>//如果結構體的執行個體就是let類型,則第一次初始化後,不能再修改其任何屬性的值</code>
<code>let rangeOfFourItems = FixedLengthRange(firstValue: 0, length: 4)</code>
<code>// this range represents integer values 0, 1, 2, and 3</code>
<code>rangeOfFourItems.firstValue = 6</code>
<code>// 将會報錯</code>
但是類不同意結構體,因為類是指針類型,将指針類型的執行個體指派給一個常量,仍然可以修改其變量成員的值。
延遲存儲屬性,在屬性聲明前部加@lazy關鍵字,必須是var類型的屬性才能是延遲屬性,延遲屬性隻有在用到時才會被計算。
15
16
17
18
19
20
21
<code>class</code> <code>DataImporter {</code>
<code>/*</code>
<code>該類的功能是從外部檔案導入資料</code>
<code>*/</code>
<code>var fileName = </code><code>"data.txt"</code>
<code>// 其他資料導入等功能此處省略</code>
<code>class</code> <code>DataManager {</code>
<code>@lazy var importer = DataImporter()</code>
<code>var data = String[]()</code>
<code>// 其他資料管理功能此處省略</code>
<code>let manager = DataManager()</code>
<code>manager.data += </code><code>"Some data"</code>
<code>manager.data += </code><code>"Some more data"</code>
<code>//在下面的語句執行以前,importer未被建立</code>
<code>println(manager.importer.fileName)</code>
<code>// 當第一次用到importer的時候,才會生成執行個體,列印"data.txt"</code>
存儲屬性:我認為就是一般的屬性,直接存儲了變量或常量,可直接通過後點(.)獲得或設定其值
計算屬性:有get方法和set(可選)方法的屬性
22
23
24
25
26
27
28
<code>struct</code> <code>Point {</code>
<code>var x = 0.0, y = 0.0</code>
<code>struct</code> <code>Size {</code>
<code>var width = 0.0, height = 0.0</code>
<code>struct</code> <code>Rect {</code>
<code>var origin = Point()</code>
<code>var size = Size()</code>
<code>var center: Point {</code>
<code>get {</code>
<code>let centerX = origin.x + (size.width / 2)</code>
<code>let centerY = origin.y + (size.height / 2)</code>
<code>return</code> <code>Point(x: centerX, y: centerY)</code>
<code>set(newCenter) {</code>
<code>origin.x = newCenter.x - (size.width / 2)</code>
<code>origin.y = newCenter.y - (size.height / 2)</code>
<code>var square = Rect(origin: Point(x: 0.0, y: 0.0),size: Size(width: 10.0, height: 10.0))</code>
<code>//調用了center的get方法,計算了Point</code>
<code>let initialSquareCenter = square.center</code>
<code>//調用了center的set方法,origin被修改了</code>
<code>square.center = Point(x: 15.0, y: 15.0)</code>
<code>println(</code><code>"square.origin is now at (\(square.origin.x), \(square.origin.y))"</code><code>)</code>
<code>// origin現在是 (10.0, 10.0)</code>
set方法可以省略參數,省略時,預設用newValue代替,如下:
<code>struct</code> <code>AlternativeRect {</code>
<code>set {</code>
<code>origin.x = newValue.x - (size.width / 2)</code>
<code>origin.y = newValue.y - (size.height / 2)</code>
隻有get方法的計算屬性是隻讀的,可以省略get,文法如下:
<code>struct</code> <code>Cuboid {</code>
<code>var width = 0.0, height = 0.0, depth = 0.0</code>
<code>var volume: Double {</code>
<code>return</code> <code>width * height * depth</code>
<code>let fourByFiveByTwo = Cuboid(width: 4.0, height: 5.0, depth: 2.0)</code>
<code>println(</code><code>"the volume of fourByFiveByTwo is \(fourByFiveByTwo.volume)"</code><code>)</code>
<code>// 列印"the volume of fourByFiveByTwo is 40.0"</code>
屬性螢幕,允許開發者在設定變量值前後執行一段代碼
<code>class</code> <code>StepCounter {</code>
<code>var totalSteps: Int = 0 {</code>
<code>willSet(newTotalSteps) {</code>
<code>println(</code><code>"About to set totalSteps to \(newTotalSteps)"</code><code>)</code>
<code>didSet {</code>
<code>//參數省略時,預設使用oldValue,willSet的參數也可省略,預設是newValue</code>
<code>//在didSet方法裡也可以修改本屬性的值,并且在次數的指派不調用willSet和didSet</code>
<code>if</code> <code>totalSteps > oldValue {</code>
<code>println(</code><code>"Added \(totalSteps - oldValue) steps"</code><code>)</code>
<code>let stepCounter = StepCounter()</code>
<code>//每設定一次totalSteps 的值,都執行willSet和didSet各一次,初始化時都不執行</code>
<code>stepCounter.totalSteps = 200</code>
<code>// About to set totalSteps to 200</code>
<code>// Added 200 steps</code>
<code>stepCounter.totalSteps = 360</code>
<code>// About to set totalSteps to 360</code>
<code>// Added 160 steps</code>
<code>stepCounter.totalSteps = 896</code>
<code>// About to set totalSteps to 896</code>
<code>// Added 536 steps</code>
全局變量一般都是計算延遲的,類似延遲存儲變量, 但是不需要在前面加@lazy關鍵字
類型屬性就是屬于類型的屬性,想C++中靜态變量,隻存在一份,在所有類的執行個體中共享。
值類型(結構體和枚舉)可以定義存儲變量和計算變量的類型屬性,而指針類型(類)隻能定義計算變量的類型屬性
而存儲類型屬性可以是var和let型的,而計算類型屬性隻能是var型的
必須給存儲類型屬性賦初值,因為類型在初始化不能對存儲類型屬性指派
<code>//聲明類型屬性</code>
<code>struct</code> <code>SomeStructure {</code>
<code>static</code> <code>var storedTypeProperty = </code><code>"Some value."</code>
<code>static</code> <code>var computedTypeProperty: Int {</code>
<code>// return an Int value here</code>
<code>enum</code> <code>SomeEnumeration {</code>
<code>class</code> <code>SomeClass {</code>
<code>class</code> <code>var computedTypeProperty: Int {</code>
<code>//使用和指派類型屬性,使用類型調用類型屬性</code>
<code>println(SomeClass.computedTypeProperty)</code>
<code>println(SomeStructure.storedTypeProperty)</code>
<code>// 列印 "Some value."</code>
<code>SomeStructure.storedTypeProperty = </code><code>"Another value."</code>
<code>// 列印"Another value."</code>