Swift 3 基礎 — Initializer
當一個物件在初始化的當下可以順便帶入, 該物件該有的變數,以便建立物件,在一個 class 在初始化時便會呼叫 init()
這一個 function,利用 init()
賦予 class 後續的 code 運行所需的所有變數初始值。
例如有一個 class Dog:
class Dog { }
你可透過下列 code 製作一個 Dog instance
Dog()
但上述的 code 沒有太大用處因為,因為你沒有給他一個參考位置,所以你在建立完之後馬上就又消失不見,xcode 會希望你給他一個存放位置。
所以我們給了他一個參考位置存放:
let dog = Dog()
如此一來,Dog
這個 class 被建立了起來並存放在 dog
,我們可以透過 dog.
來取得這個 class 底下的所有公開資訊。
你可以觀察到一點,在你建立這個 dog
你可以發現到 Dog()
使用了圓括號 ()
,代表這你建立的同時呼叫了隱含初始化 (implicit initializer)init()
。
這個 init()
是系統預設的,讓你方便的初始化這個 class 當你沒有建立自訂的 Initializer 時,他便會自動的呼叫這個 init()
。
Custom Initializers
上述的 Dog()
裡面並沒有放入任何的變數,在一般的開發環境中,我們會習慣在一個 class 放入一至多個變數,讓 class 裡的任何 function 可以運用這些變數。
我們在這個 Dog()
裡加入了兩個變數,並加入 Initializers。
接下來你就可以依照不同的情境下去使用這些 Initializer:
但你不能再繼續使用:
let dog = Dog()
原因是當你一旦建立了自定義的 Initializer 之後,這個 init()
便不存在這個 class 裡了,你可以透過明確的定義 explict Initializer 來建立。
如此一來,又可以使用這個 init()
了。
我們可以不需要把每一個初始化都寫成一個,事實上,我們只需要寫一個 initializer 即可!
可以寫成這樣的原因是,initializer 其實就是一個特別的 function,而 function 本質上是可以在參數定義自己的初始值的,而我們這樣做的同時,原本的定義出來的實體還是可以繼續使用。
更有趣的一點是,initializer 定義出來之後,就可以在上面的變數定義時,不需要直接傳入任何值,只需要定義變數的 type 即可。
請注意一點,在 swift 中每一個變數都需要一個初始值,跟 objc 有很大的差異,所以以下是一個錯誤的初始化方式:
你可以在一開始定義時使用常數 constants let
,原因是因為 initializer,就是專門為變數或常數設定初始值。
在實際的應用上,這樣子做的意義是,我們希望呼叫這個 class 的時候 ”必須“ 帶入所有包含的參數。
Optional properties
思考一下,在某些情境的使用上,可能會遇到在初始化的時候,沒有辦法馬上帶入應有的參數時改怎麼辦呢?
- 使用預設值
2. 使用 optional warped
還記得 optional 的宣告其實是宣告一個 Optional(type) 嗎?
我們可以利用這個特點將 name 定義成 一個 unwarped optional String String!
因此這一個變數就有了解包可選字串,等到真正要傳入變數時才在傳入,這樣在後續的 code 可以直接地去使用,如下列範例:
Referring to self
所有的 properties 在 class 還沒賦予初始值之前,class 都無法被使用,直到所有 properties 都有初始值:
上面中的 bark()
其實是隱含了 self.bark()
,在所有的 properties 都有直之前都不能使用 class 裡的 func,必須把 bark()
往下移動一行,才能做使用。
Failable initializer
initializer 可以是可以失敗的,當某些帶入的直沒有達到特定的條件時,class 將沒有辦法初始化,要使用可失敗的 initializer 必須在 init 加入 ?
如下:
返回一個 nil 代表這個 class 沒有被建立,也就是說無論這個 class 可以被建立與否,他都是一個 optional(type),代表著要使用這個實體都必須 unwarped。