2015-04-16 101 views
20

我有一個這樣的簡單類。從初始化程序返回而不初始化所有存儲的屬性

public class User { 
    let id: Int 
    let firstName: String 
    let lastName: String 
    let email: String? 

    init(id: Int, firstName: String, lastName: String) { 
     self.id = id 
     self.firstName = firstName 
     self.lastName = lastName 
    } 
} 

這在以前的Swift版本中編譯得很好。在Swift 1.2中,我收到了以下編譯錯誤。從初始

返回,無初始化所有存儲性能

這是爲什麼,我該怎麼解決呢?

回答

27

如果一個屬性是恆定的,用let創建,則必須在原地或在init方法中初始化它,即使它是Optional。如果您希望能夠選擇設置電子郵件,則應將let更改爲var。換句話說,如果你沒有在初始化方法或類體中初始化變量,那麼變量必須是varOptional

相關語句在docs

您可以初始化過程中的任何點值分配給一個不變的性質,只要它被設置爲按時間完成初始化一個定值。一旦一個常量屬性被分配一個值,它就不能被進一步修改。

對於類實例,常量屬性只能在初始化期間由引入它的類修改。它不能被子類修改。

+1

如果使用'let'或'var',則無關緊要。您必須在初始化程序中設置它以避免編譯錯誤。我有同樣的錯誤,但沒有使用任何'let'變量,這個錯誤也出現了。所以我不得不刪除或設置這個變量來避免這個編譯錯誤。 – Jurik

+0

@Jurik在'可選'的情況下,它確實很重要,否則它就是你說的。 –

+0

@DánielNagy你的回答措辭的方式有點誤導,因爲在快速閱讀時,它會導致人們相信改變讓var來解決錯誤。事實上,有兩件事情是需要的:1)改變讓var,2)使用可選項 – VKK

1

首先要明確的是每個let變量都必須在聲明時賦值。所以你的陳述將是

let id: Int = 0 
let firstName: String = "test" 
let lastName: String = "Test" 
let email: String? = "Test" 

其次在類中,你必須初始化變量或定義它們作爲可選類型,通過將'?'要麼 '!'與每個變量。像

let id: Int! 
let firstName: String! 
let lastName: String! 
let email: String? 

let id: Int? 
let firstName: String? 
let lastName: String? 
let email: String? 

,但要你在這裏說,這些變量將無法改變,因爲它們是常數。所以如果你在申報時沒有傳遞價值,你必須使用var。在這種情況下,您的最終代碼將是某種此類

var id: Int 
var firstName: String 
var lastName: String 
var email: String? 
11

您需要明確設置電子郵件的值,因爲它是常量。

public class User { 
    let id: Int 
    let firstName: String 
    let lastName: String 
    let email: String? 

    init(id: Int, firstName: String, lastName: String) { 
     self.id = id 
     self.firstName = firstName 
     self.lastName = lastName 
     self.email = nil // <-------------- 
    } 
} 

或者像其他人提到的那樣,您可以將電子郵件更改爲變量。

+0

是的,上面的答案是正確的。 –

3

將電子郵件從「let」更改爲「var」,如下所示。

public class User { 
    let id: Int 
    let firstName: String 
    let lastName: String 
    var email: String? 

    init(id: Int, firstName: String, lastName: String) { 
     self.id = id 
     self.firstName = firstName 
     self.lastName = lastName 

    } 
} 
13

經驗法則是:

  • 如果你讓,你需要初始化它(即使它是可選的)。例如:let email: String
  • 如果您有一個非可選var您需要初始化。例如var email: String
  • 如果你有一個可選的var,你不需要初始化它。例如var email: String?