2016-01-28 20 views
4

這是從文檔,部分Failable Initializers for Classes在這個例子中使用隱式解包可選的點是什麼?

class Product { 

    let name: String! 
    init?(name: String) { 
      self.name = name 
      if name.isEmpty { return nil } 
    } 
} 


if let bowTie = Product(name: "") { 
    // no need to check if bowTie.name == nil 
    print("The product's name is \(bowTie.name)") 
} 

這等進行了說明:

在上面的例子中,產品類​​的名稱屬性是 定義爲具有一個隱式展開的可選字符串類型 (字符串!)。因爲它是一個可選的類型,這意味着名 酒店零的默認值是在初始化過程中分配一個特定 值之前。反過來零的此默認值意味着 所有由產品介紹類的屬性有 有效的初始值。其結果是,對於產品 的failable初始值設定,如果它傳遞一個空字符串,分配一個特定的值 初始化中的name屬性之前,在初始化 開始觸發初始化失敗。

看看最後一句:

其結果是,在failable初始化爲產品 如果它傳遞一個空字符串可以在初始化 開始觸發初始化失敗,然後在初始化程序中爲 指定名稱屬性的特定值。

這不能從所提供的代碼看到。在所提供的代碼,它可以看出,分配之前return nil部分已經發生,並且或者字符串(非可選)或字符串? (可選)將工作。

另一件事是,在提供的例子,它是沒有意義的使用隱式展開可選的,如果它被定義爲常數。在init完成之前,必須將常量初始化爲默認值。

任何對此的思考,或沒有任何人看到的不提交這個雷達的原因嗎?也許我錯過了什麼?我實際上有一個想法,爲什麼在這裏使用隱式解包可選,但這是一個不好的例子。對我來說,這會更有意義:

class Product { 

    var name: String! //let is changed to var 

    init?(name: String) { 

     if name.isEmpty { return nil } //Check here if passed value is non-empty 
     self.name = name 
    } 
} 

這樣,一個初始化失敗可以任意分配給name屬性之前被觸發。

+0

請注意,就你最後一個例子而言,Swift會抱怨(編譯時錯誤),在從failable初始化者返回'nil'之前,屬性'name'尚未初始化。 < - 編輯:你的'name'了一個可變:) – dfri

+0

@dfri確定的編輯後不再?名稱被聲明爲var(並且隱式地解包可選),所以它會起作用。 – Whirlwind

+0

@Whirlwind注意我的編輯註釋:這算是你之前,你的例子,從一成不變的改變'name'以可變的。 – dfri

回答

3

所有你的誤導性資料的擔憂是正確的。

而且,請注意,雨燕2.2從failable初始化月初回國確實工作,所有屬性被初始化之前也:

class Product { 
    let name: String 
    init?(name: String) { 
     if name.isEmpty { return nil } 
     self.name = name 
    } 
} 

另一個變化是,deinit不叫任何更多的時候從可分解的初始化程序返回零。

在Xcode 7。3的β2 Release Notes

裏面一個類別,指定初始化要麼是failable(init?())或投擲(init() throws)正在初始化所有存儲的屬性並調用super.init()之前允許退出。支持此行爲,使指定的初始值設定項與便捷初始值設定項更加一致。在執行self.init()委派之前,便利初始值設定程序也可能失敗。

+0

出於某種原因,看起來好像後面的語句(早期返回)在Swift 2.1中對於包含_immutables_(奇怪?)的隱式解包可選屬性的類是不正確的。但是這在Swift 2.2中會好嗎? (例如,試圖早日迴歸,你有一個'讓富:在String類'屬性) – dfri

+0

@dfri我沒有和它爲我工作。 –

+0

我指的是隱式地展開可選屬性的特殊情況下(如由OP討論的),例如'let name:String!'(注意'!')。 – dfri

相關問題