2015-04-16 56 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?