【问题标题】:Return from initializer without initializing all stored properties从初始化程序返回而不初始化所有存储的属性
【发布时间】:2015-06-22 18:53:17
【问题描述】:

我有一个像这样的简单课程。

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 中,我收到以下编译错误。

从初始化程序返回而不初始化所有存储的属性

为什么会这样,我该如何解决?

【问题讨论】:

    标签: ios class swift


    【解决方案1】:

    如果属性是常量,因此使用let 创建,则必须在原地或在init 方法中对其进行初始化,即使它是Optional。如果您希望能够选择性地设置电子邮件,您应该将let 更改为var。换句话说,如果您没有在 init 方法或类主体中初始化变量,则该变量必须同时是 varOptional

    docs中的相关语句:

    您可以在初始化期间的任何时候为常量属性赋值,只要在初始化完成时将其设置为确定的值即可。一旦一个常量属性被赋值,它就不能被进一步修改。

    对于类实例,常量属性只能在初始化期间由引入它的类修改。它不能被子类修改。

    【讨论】:

    • 使用letvar都没有关系。您必须在初始化程序中设置它以避免此编译错误。我在没有使用任何let 变量的情况下遇到了同样的错误,并且这个错误也出现了。所以我不得不删除或设置这个变量以避免这个编译错误。
    • @Jurik 在“可选”的情况下,它确实很重要,否则你所说的就是真的。
    • @DánielNagy 您的回答措辞方式有点误导,因为快速阅读会让人相信将 let 更改为 var 会解决错误。实际上,需要做两件事:1)将 let 更改为 var,以及 2)使用 optionals
    • @DánielNagy 我确实意识到在 OP 的情况下,他的常量 Optional email 变量导致了错误,所以唯一需要的改变是将其更改为 var,但我认为值得为其他读者澄清这一点看看你的答案。我修改了答案以使其更加清晰。
    【解决方案2】:

    经验法则是:

    • 如果你已经让,你需要初始化它(即使它是可选的)。例如:let email: String
    • 如果您有一个非可选变量,您需要进行初始化。例如var email: String
    • 如果您有可选的 var,则无需对其进行初始化。例如var email: String?

    【讨论】:

      【解决方案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
      
          }
      }
      

      【讨论】:

        【解决方案4】:

        您需要为电子邮件显式设置一个值,因为它是一个常量。

        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 // <--------------
            }
        }
        

        或者正如其他人提到的,您可以将电子邮件更改为变量。

        【讨论】:

          【解决方案5】:

          首先要明确每个 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?
          

          【讨论】:

            猜你喜欢
            • 2017-12-31
            • 1970-01-01
            • 2023-03-28
            • 1970-01-01
            • 1970-01-01
            • 2020-07-09
            • 1970-01-01
            • 2017-01-07
            • 2021-06-28
            相关资源
            最近更新 更多