2015-07-28 1 views
1
muter

J'essaie de comprendre comment mettre en œuvre le modèle de commande à Swift. Jusqu'à présent, ce code fonctionne très bien:modèle de commande à Swift aux méthodes de struct

class Subject 
{ 
    var value: Int = 0 

    func setValue(value: Int) { 
     self.value = value 
    } 
} 

class Command<T> 
{ 
    private var receiver: T 
    private var instructions: T -> Void 

    init(receiver: T, instructions: T -> Void) { 
     self.receiver = receiver 
     self.instructions = instructions 
    } 

    func execute() { 
     instructions(receiver) 
    } 
} 

var subject = Subject() 

println(subject.value) // "0" 

let instructions: Subject -> Void = { sub in Subject.setValue(sub)(2) } 
let command = Command<Subject>(receiver: subject, instructions: instructions) 
command.execute() 

println(subject.value) // "2" 

Cependant, si je veux que le récepteur soit un struct au lieu d'un class, le même code ne fonctionne pas. Donc, si je définis comme sujet struct comme suit:

struct Subject 
{ 
    var value: Int = 0 

    mutating func setValue(value: Int) { 
     self.value = value 
    } 
} 

Puis-je obtenir l'erreur: « Le sujet est non convertible en inout Objet » sur let instructions: Subject -> Void = { sub in Subject.setValue(sub)(2) }.

Je ne sais pas comment aborder ce sujet. Toute suggestion?

+1

Cela pourrait être difficile. Notez que 'self.receiver = receiver' dans la méthode Command init fait déjà une copie * indépendante * de la structure. –

+0

Si vrai ... Ce qui me fait penser si j'ai ce problème en raison d'une mauvaise idée de conception. Peut-être que cela n'a pas beaucoup de sens, en général, d'appliquer le modèle de commande sur un objet struct ("value") (?) Merci! – George

Répondre

0

Le problème est que si vous voulez appeler une méthode de classe sur un objet, vous devez passer un paramètre inout. Cela se fait par l'ajout d'un & devant la variable:

Subject.setValue(&subject)(2) 

Cependant, vous ne pouvez pas le faire à partir d'une méthode anonyme, vous devez taper comme un paramètre inout explicitement.

Je pense que ce code devrait fonctionner, mais dans mon cas, il se bloque et aire de jeux Xcode Xcode REPL:

struct Subject 
{ 
    var value: Int = 0 

    mutating func setValue(value: Int) { 
     self.value = value 
    } 
} 

class Command<T> 
{ 
    private var receiver: T 
    private var instructions: inout T -> Void 

    init(inout receiver: T, instructions: inout T -> Void) { 
     self.receiver = receiver 
     self.instructions = instructions 
    } 

    func execute() { 
     instructions(&receiver) 
    } 
} 

var subject = Subject() 

println(subject.value) // "0" 


var instructions: inout Subject -> Void = { sub in Subject.setValue(sub)(2) } 
let command = Command<Subject>(receiver: &subject, instructions: instructions) 
command.execute() 

println(subject.value) // "2"