2016-09-01 3 views
2

Ich habe zwei Klasse ändern, die aus demselben ProtokollWie können wir Variable Protokoll in Swift

protocol MyProtocol{ 

} 
class MyFirstClass : MyProtocol{ 
    var test : Int = 0 
} 
class MySecondClass : MyProtocol{ 
    var test : Int = 0 
} 

implementiert Wie kann ich eine Funktion, die Testgröße erhöht jedes Mal, wenn ich Pass Objekt von MyFirstClass oder MySecondClass

so etwas wie dies

var a = MyFirstClass() 
var b = MySecondClass() 

func inc(myObject : MyProtocol){ 
    myObject.test ++ // myObject has no member `test` 
} 

inc(a) 
inc(a) 
inc(b) 
inc(a) 
+0

Sie konkrete Funktionen zu einem 'extension' des Protokolls hinzufügen können. Ich denke, dass ist das, was Sie untersuchen müssen, aber ich bin mir nicht sicher, ob ich Ihre Frage vollständig verstanden habe ... – Grimxn

Antwort

3

Dies ist der komplette Swift 3-Code:

protocol MyProtocol: class { 
    var test: Int { get set } 
} 

class MyFirstClass: MyProtocol { 
    var test: Int = 0 
} 

class MySecondClass: MyProtocol { 
    var test: Int = 0 
} 

func inc(_ obj: MyProtocol) { 
    obj.test += 1 
} 

var a = MyFirstClass() 
var b = MySecondClass() 

inc(a) 
print(a.test) // 1 
inc(a) 
print(a.test) // 2 
inc(b) 
print(b.test) // 1 
inc(a) 
print(a.test) // 3 

Wichtiger Hinweis:

ich class MyProtocol nur gemacht haben, da dieser Code-Optimierung ermöglichen.

Wenn Sie es auf jede Art (nicht nur Klassen) möchten, können Sie annehmen @Hamish solution (Sie mehr darüber in den Kommentaren unten lesen)

+0

Nur weil 'MyProtocol' nicht klassengebunden ist (': class'), heißt das nicht dass Instanzen von 'MyFirstClass' oder' MySecondClass' kopiert werden, wenn sie an die 'inc (_ :)' -Funktion übergeben werden - sie haben immer noch Referenzsemantik (zB Schreiben der Funktion als 'func inc (_ obj: MyProtocol) {var obj = obj; obj.test + = 1} 'würde in diesem Fall immer noch funktionieren. Wenn die Klasse 'MyProtocol' gebunden wird, werden übereinstimmende Typen als Klassen definiert. Daher kann der Compiler Instanzen behandeln, die als 'MyProtocol' als Referenztypen eingegeben wurden. So können Sie ein Element in der Funktion direkt in' obj' mutieren. – Hamish

+0

Ich verstehe, was Sie meinen: Ihr Beispiel '' func inc (_ obj: MyProtocol) {var obj = obj; obj.test + = 1} '' ändert die ursprüngliche Instanz nicht. Von dem, was ich sehe, möchte OP die ursprüngliche Instanz ändern. Was Sie über die Einschränkung des Protokolls gesagt haben, ist wahr, und da OP zwei Klassen als Beispiel verwendet hat, fühlte ich mich OK, wie ich es tat (es macht auch Sinn, es leistungsmäßig zu beschränken, wenn Sie es nur für Klassen verwenden). –

+1

Mein Beispiel würde die 'test'-Eigenschaft der ursprünglichen Instanz ändern ([Probieren Sie es selbst aus]) (https://swiftlang.ng.bluemix.net/#/repl/57c82141688f27dd6f430c71)). Ich stimme zu, dass es in diesem Fall tatsächlich Sinn macht, dass das Protokoll klassengebunden ist. Ich stimme nur nicht mit dem Teil Ihrer Antwort überein, der besagt: "Andernfalls, wenn Sie die Funktion' inc (_ :) 'aufrufen, werden Sie Übergeben Sie eine Kopie Ihrer 'MyFirstClass' /' MySecondClass' -Instanz * " – Hamish

Verwandte Themen