2017-08-29 41 views
-2

我如何使用惰性初始化與getset()關閉。如何使用getter/setter方法進行延遲初始化?

這是懶惰的初始化代碼:

lazy var pi: Double = { 
     // Calculations... 
     return resultOfCalculation 
     }() 

,這裏是的getter/setter代碼:

var pi: Double { 
    get { 
     //code to execute 
     return someValue 
    } 
    set(newValue) { 
     //code to execute 
    } 
} 
+0

爲什麼你需要那個?有什麼具體原因嗎? – karthikeyan

+0

1.那些不是關閉2.吸氣者在被調用之前不會運行。你想達到什麼目的? –

+1

你如何預測這個工作?有了「懶惰」屬性,它被設置爲第一次訪問。使用setter時,只要使用setter就會立即設置。你想要一個默認的懶惰getter和一個明確的setter?請添加更多細節。 – ColGraff

回答

1

我假設你正在試圖做的是懶洋洋地產生可寫屬性的默認什麼。我經常發現,當人們不需要時,人們就會懶惰。確保這真的是值得的麻煩。如果默認值很少使用,這將是值得的,但創建相當昂貴。但如果這是你的情況,這是做到這一點的一種方式。

lazy實現了一個非常具體和相當有限的模式,這通常不是你想要的。 (lazy對於它的工作原理是一種有價值的補充,並且正在積極地將它替換爲一個更強大和更有用的屬性系統)。當lazy不是您想要的工具時,你只是建立你自己的。在你的榜樣,它應該是這樣的:

private var _pi: Double? 
var pi: Double { 
    get { 
     if let pi = _pi { return pi } 
     let result = // calculations.... 
     _pi = result 
     return result 
    } 

    set { _pi = newValue } 
} 

這就是說,在大多數情況下,我已經看到了這一點上來,最好在初始化使用默認值:

func computePi() -> Double { 
    // compute and return value 
} 

// This is global. Globals are lazy (in a thread-safe way) automatically. 
let computedPi = computePi() 

struct X { 
    let pi: Double // I'm assuming it was var only because it might be overridden 
    init(pi: Double = computedPi) { 
     self.pi = pi 
    } 
} 

這樣做只會在整個程序中計算一次pi(而不是每個實例一次)。它讓我們使pi「寫入 - 一次一次」而不是可變狀態。 (這可能會也可能不符合您的需求;如果它確實需要可寫,則var。)

類似的默認值方法可用於構建昂貴的對象(而不是靜態的東西,計算)而不需要全局。

struct X { 
    let pi: Double 
    init(pi: ExpensiveObject = ExpensiveObject()) { 
     self.pi = pi 
    } 
} 

但有時候吸氣劑和固定劑更合適。

1

lazy變量的要點在於,它在獲取之前不會被初始化,從而阻止其初始化器(可能代價昂貴)運行,直到訪問該變量的值。

那麼,這正是計算變量的吸氣器呢!它不會運行,除非它被調用。因此,計算變量的吸氣劑爲懶惰。

這個問題總的來說是沒有意義的。 (短語「我如何使用延遲初始化」揭示了這個缺陷,因爲計算的變量是從未初始化 - 它是計算!)