2017-03-12 1 views
0

Je veux créer une classe, de sorte que ses sous-classes après avoir appelé une fonction a, recevront un nouvel objet de type Self. J'assure, que les sous-classes auront la méthode init().Instantiate Self en dehors de init dans Swift

D'une certaine manière, je veux cloner l'objet, mais en réalité il est plus que cela, puisque je veux créer un clone avec des valeurs modifiées de l'original, donc je ne veux pas vraiment utiliser la syntaxe du constructeur de copie swifty

Pourquoi cela ne fonctionne-t-il pas? Certainement ceci:

func myCustomCopy(modificationCommand: Command) -> Test { 
    let newInt = modificationCommand.execute(self.myInt) 
    return Test(newInt: newInt) 
} 

est pas ce que je veux.

Exemple:

protocol Testable { 
    var myInt: Int { get set } 
    init(newInt: Int) 
} 

class Test: Testable { 
    var myInt = 10 
    required init(newInt: Int) { myInt = newInt } 

    func myCustomCopy(modificationCommand: Command) -> Self { 
     let newInt = modificationCommand.execute(self.myInt) 
     return self.init(newInt: newInt) 
    } 
} 
+1

1) Pourquoi n'est-ce pas ce que vous voulez? – Alexander

+0

2) Pourquoi avez-vous besoin d'une fonction 'a()' en premier lieu? – Alexander

+0

3) Le dernier extrait de code est totalement correct si vous supprimez simplement la fonction 'a()' entièrement. Chaque sous-classe aura besoin d'avoir cet initialiseur, et il retournera toujours le même type de la sous-classe – Alexander

Répondre

1

Vous pouvez utiliser le (typé dynamiquement) métatype retourné par type(of:) pour accéder à un initialiseur du type concret de la métatype. Citant le Language Reference - Metatypes

utiliser une expression d'initialisation pour construire une instance d'un type de la valeur de métatype de ce type. Pour les instances de classe, l'initialiseur appelé doit être marqué du mot-clé required ou de l'intégralité de la classe marquée du mot-clé final.

Donc dans votre cas, vous pouvez utiliser métatype de self pour appeler un initialiseur required du type de béton self, par exemple

func myCustomCopy() -> Self { 
    return type(of: self).init() 
} 

Notez que, comme indiqué dans la citation ci-dessus, puisque vous travaillez avec une classe non-finale, l'initialiseur doit être un required un.