今天會學到
屬性簡單來說(property)是特定型別(class、struct、enum)的值
在最簡單的形式中,儲存屬性就是儲存在(class, struct)的常數或變數
struct DiscountCalculator {
var price:Float = 0 //這兩行都是儲存屬性
var discount:Float = 0
}
第一次呼叫使用的時候才會初始化,只能使用var變數來宣告,因為let常數建立時就一定要有初始值。
當屬性的初始值需要進行大量運算時,lazy很有用,可以節省很多效能跟時間。
class Count {
// 延遲儲存屬性
lazy var handleCount = DiscountCalculator()
}
計算屬性不直接儲存值,而是使用儲存屬性來進行計算,我們用上面的範例延伸。
假設我們要設計一款折扣計算機,我們用struct建立一個計算機的功能,裡面可以儲存金額跟折扣,再來就會有折扣後的金額,那這個折扣後的金額我們就可以使用計算屬性因為他需要用到金額跟折扣這兩個儲存屬性。以下是範例
struct DiscountCalculator {
var price:Float = 0 //這是儲存屬性
var discount:Float = 0
var priceAfterDiscount:Float { //這是計算屬性,把金額跟折扣相乘就會等於最終價格
return price * discount
}
}
這個是一個非常好用的東西,他會隨時監控數值,如果數值改動的話就會觸發你寫的程式碼內容。在觀察器中我們有兩種東西可以使用:
willSet
:每次值被改動前,會把新的值當作參數傳入給willSet裡面用,可以自己命名參數,不然預設就會是newValue
didSet
:在之後的每次值被改動後,就會執行didSet程式碼裡的內容,舊的值會當作參數傳入使用,可以自己命名參數,如果沒有的話就會預設oldValue
下面我們引用官方文件的範例
class StepCounter {
var totalSteps: Int = 0 {
willSet(newTotalSteps) { //設定新的值的參數叫做newTotalSteps
print("About to set totalSteps to \(newTotalSteps)")
}
didSet { //沒有設定參數所以原本的值使用預設oldValue
if totalSteps > oldValue {
print("Added \(totalSteps - oldValue) steps")
}
}
}
}
let stepCounter = StepCounter() //都要先實例化物件才可以使用
stepCounter.totalSteps = 200 //當我們賦予新的值為200時
// 印出 About to set totalSteps to 200
// 印出 Added 200 steps
stepCounter.totalSteps = 360 //再賦予新的值為360
// 印出 About to set totalSteps to 360
// 印出 Added 160 steps
簡單來說我們使用static
來宣告常數或是變數,這樣不需要實例化就可以使用type property,但其他人想要取得type property也只能透過專屬的class/struct拿到,不能從其他地方拿到。之前有講到class跟struct是一種藍圖,所以實例化就是把藍圖的東西製作成真實物品的概念。
struct DiscountCalculator {
var price:Float = 0
}
let caculate = DiscountCalculator() //先實例化
print(caculate.price) //取用裡面的數字
struct Discount {
static var price:Float = 0 //使用型別屬性
}
print(Discount.price) //不需要實例化就可以直接取用
簡單來說你可以想像這型別屬性是一種共享雲端資料的概念,你永遠只能從那個雲端拿到資料。之後的章節會提到什麼情況會這樣使用。