以下兩種變數宣告有何差別?
var 奈秒 = 100 + 1
var 奈秒二: Int {
return 100 + 1
}
雖然兩者都是經過「運算」來設定變數值,但第一種用等號的稱為 “stored property” (儲存變數或儲存屬性),第二種用 { } 稱為 “computed property” (計算變數或計算屬性),要了解兩者的差別,必須先懂一點程式語言的基礎理論。
當我們在 Swift Playgrounds 按下「執行我的程式碼」,程式是如何執行的呢?其實可細分為三個階段:
一般較常用的 “stored property”,在第二階段就會確定記憶體位置,也就是在執行階段之前就先配置好記憶體儲存空間;而 “computed property” 則是在第三階段,也就是執行階段(run-time),才會臨時配置記憶體以暫存計算結果。
這兩者有點像某些演唱會,預售階段買票的人,可以事先劃座位,開演前就能知道自己位置,就像 “stored property”;臨時買票進場的人,沒有固定座位(自由座),”computed property”就是如此,沒有固定的記憶體位置。
為什麼 extension 擴充物件時,擴增屬性只能用 “computed property” 來設定呢?這是因為執行到 extension 之前,可能就已有該物件的實例存在,當 extension 擴增屬性之後,那些已存在的物件實例如何增加新的屬性呢?當然不可能回頭預留座位(記憶體空間),所以只能在執行階段動態配置了。
想知道自己對於 “Computed property” 與 “Stored property” 是否已了解,可以測試以下小程式,猜猜看這兩段程式碼的輸出是否一樣?
// 4-4e Computed property
// Tested by Heman, 2022/04/16
import Foundation
var 奈秒 = Calendar.current.component(.nanosecond, from: Date())
print(奈秒, 奈秒, 奈秒)
var 奈秒二: Int {
Calendar.current.component(.nanosecond, from: Date())
}
print(奈秒二, 奈秒二, 奈秒二)
這個測試的輸出有點令人意外。第一段用 stored property 宣告的「奈秒」,輸出結果是3個同樣的數值,很正常,但是第二段用 computed property 宣告的「奈秒二」,輸出結果不僅跟「奈秒」值不同,而且3個數值竟然彼此也不一樣,為什麼會這樣?
var 奈秒 = Calendar.current.component(.nanosecond, from: Date())
print(奈秒, 奈秒, 奈秒)
// 輸出結果:493368983 493368983 493368983
var 奈秒二: Int {
Calendar.current.component(.nanosecond, from: Date())
}
print(奈秒二, 奈秒二, 奈秒二)
// 輸出結果:496469974 496510982 496538043
用 stored property 宣告的變數「奈秒」,等號之後的運算只會計算一次,計算結果儲存在「奈秒」所在的記憶體位置上,之後引用「奈秒」時,就從記憶體位置上取值,所以總是取得同樣的值。