Return from initializer without initializing all stored properties

Solution 1:

If a property is constant, so created with let, you have to initialize it in place or in the init method, even if it is an Optional. If you want to be able to set email optionally, you should change let to var. In other words, if you are not initializing a variable in either the init method or class body, then the variable must be both a var and an Optional.

Related statements in the docs:

You can assign a value to a constant property at any point during initialization, as long as it is set to a definite value by the time initialization finishes. Once a constant property is assigned a value, it can’t be further modified.

For class instances, a constant property can only be modified during initialization by the class that introduces it. It cannot be modified by a subclass.

Solution 2:

The rule of thumb is:

  • If you have let, you need to initialize it (even if it is optional). Eg : let email: String
  • If you have a non optional var you need to initialize. Eg var email: String
  • If you have an optional var you don't need to initialize it. Eg var email: String?

Solution 3:

You need to explicitly set a value for email since it is a constant.

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

Or as the others mentioned you can change email to a variable.

Solution 4:

Change the email from "let" to "var" as below.

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

    }
}