2014-06-22 12 views
6

nicht zuweisen Ich habe gerade ein sehr einfaches Protokoll und eine Klasse mit Generika definiert, die mit diesem Protokoll umgehen können.Protokoll: Kann 'X' in 'Y' in Swift

In den Zeilen mit Fehler markiert man den Fehler bekommen. „Kann nicht zu‚Flagge‘in‚AOBJ‘zuordnen

protocol Flag { 
    var flag: Bool {get set} 
} 


class TestFlag<T: Flag> { 

    func toggle(aObj: T) { 

     if aObj.flag { 
      aObj.flag = false; // <--- error 
     } else { 
      aObj.flag = true; // <--- error 
     } 
    } 
} 

Haben Sie eine Ahnung, warum und was muss ich ändern fix it

+0

Kopieren Sie es einfach in einen Spielplatz zu testen – Stephan

Antwort

6

Vom docs:

Function parameters are constants by default. Trying to change the value of a function parameter from within the body of that function results in a compile-time error. This means that you can’t change the value of a parameter by mistake.

In diesem Fall Sie inout so dass der Knebel pe hinzufügen kann, ist rsisted über Ihre Funktionsaufruf:

func toggle(inout aObj: T) {   
    if aObj.flag { 
     aObj.flag = false; 
    else { 
     aObj.flag = true; 
    } 
} 

Sie könnten auch getan haben:

func toggle(var aObj: T) { 
} 

aber das ist vielleicht nicht das erreichen, was Sie wollten.

+2

Warum ein Downvote? – manojlds

+0

Ich hatte das gleiche Problem, aber in meinem Fall war aObj eine Eigenschaft der Klasse. Ich musste 'var aObj = self.aObj; aObj.flag = true' –

2

Manojlds Antwort ist korrekt und daher habe ich es akzeptiert.

Dennoch gab es vor einigen Tagen eine ähnliche Antwort mit der gleichen Lösung, aber mit einer anderen Argumentation (scheint jetzt gelöscht).

Die Argumentation war, dass der Complier nicht wissen kann, ob das Protokoll für eine Klasse, eine Struktur oder eine enum verwendet wird. Mit Swift können Protokolle auf alle diese Typen angewendet werden. Aber struct-Instanzen verwenden einen by-value-Aufruf und für Klassen-Instanzen (objects) einen Aufruf als Referenz.

Aus meiner Sicht diese Antwort war zu korrigieren, weil Sie das Problem mit einer zweiten Lösung lösen können:

@objc 
protocol Flag { 
    var flag: Bool {get set} 
} 

einfach das @obj attriute auf dem Protokoll hinzuzufügen. Infolgedessen können Sie dieses Protokoll nur für eine Klasse verwenden, die nur durch-Reference-Calls zu dem Ergebnis führt. Daher benötigt der Compiler nicht mehr die inout Information.

Aber ich suchte nach einer Lösung, um die Wiederverwendung des Protokolls zu erhöhen und jetzt manojlds Vorschläge zu verwenden.

+4

Sie können dies auch tun ... Protokoll Flag: Klasse {...} –

Verwandte Themen