web-dev-qa-db-fra.com

Retour de l'initialiseur sans initialiser toutes les propriétés stockées

J'ai une classe simple comme celle-ci.

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

Cela a été très bien compilé dans la précédente Swift version. Dans Swift 1.2, j'obtiens l'erreur de compilation suivante.

Retour de l'initialiseur sans initialiser toutes les propriétés stockées

Pourquoi cela et comment puis-je le résoudre?

34
Isuru

Si une propriété est constante, donc créée avec let, vous devez l'initialiser sur place ou dans la méthode init, même s'il s'agit d'un Optional. Si vous souhaitez pouvoir définir le courrier électronique en option, vous devez remplacer let par var. En d'autres termes, si vous n'initialisez pas une variable dans la méthode init ou le corps de classe, la variable doit être à la fois un var et un Optional.

Déclarations associées dans le docs :

Vous pouvez affecter une valeur à une propriété constante à tout moment pendant l'initialisation, tant qu'elle est définie sur une valeur définie au moment où l'initialisation se termine. Une fois qu'une propriété constante a reçu une valeur, elle ne peut plus être modifiée.

Pour les instances de classe, une propriété constante ne peut être modifiée lors de l'initialisation que par la classe qui l'introduit. Il ne peut pas être modifié par une sous-classe.

53
Dániel Nagy

La règle d'or est la suivante:

  • Si vous l'avez laissé, vous devez l'initialiser (même s'il est facultatif). Par exemple : let email: String
  • Si vous avez un var non optionnel vous devez initialiser. Par exemple var email: String
  • Si vous avez un var optionnel, vous n'avez pas besoin de l'initialiser. Par exemple var email: String?
23
Tiago Almeida

Vous devez définir explicitement une valeur pour le courrier électronique car il s'agit d'une constante.

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

Ou, comme les autres l'ont mentionné, vous pouvez remplacer le courrier électronique par une variable.

17
Onato

Changez l'email de "let" en "var" comme ci-dessous.

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

    }
}
6
Chamath Jeevan

Tout d'abord, précisez que chaque variable let doit recevoir une valeur au moment de la déclaration. Vos déclarations seront donc

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

Deuxièmement, dans les classes, vous devez initialiser les variables ou les définir comme types facultatifs en mettant "?" ou '!' avec chaque variable. Comme

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

ou

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

Mais je veux vous dire ici que ces variables ne pourront pas changer car ce sont des constantes. vous devez donc utiliser var avec ceux-ci si vous ne transmettez pas de valeur au moment de la déclaration. Votre code final dans ce cas sera une sorte de ceci

var id: Int
var firstName: String
var lastName: String
var email: String?
4
Saad