2017-12-14 3 views
-1

Ich habe eine Swift-Struktur, in der zwei der Membervariablen sind Verschlüsse:Zuordnung Verschluss Variable in initialiser auf struct

struct SettingsItem { 
    var title: String = "" 
    var textColor: UIColor = #colorLiteral(red: 0, green: 0, blue: 0, alpha: 1) 
    var selected:() -> Bool = { return false } 
    var action:() -> Void = { } 
} 

Wenn ich versuche, eine Instanz dieser Struktur zu erstellen, erhalte ich einen Fehler User of unresolved identifier 'selected'. Beispiel:

var settingsItem = SettingsItem(title: "Title", selected = { return true }, action = {}) 

Wenn ich die Variablen separat zuweisen, es funktioniert:

var settingsItem = SettingsItem() 
settingsItem.title = "" 
settingsItem.selected = { return true } 

Wie kann ich diesen Fehler beheben? Ich erstelle ein großes Array von SettingsItem s, so wird es viel sauberer Code sein, wenn ich Initialisierer anstelle der ausführlicheren Option verwenden kann.

+1

Das erste Problem nennen kann, ist, dass die Argumente sind als 'ausgewählt: ...', nicht 'ausgewählt = ...' –

+0

Und das zweite Problem ist, dass textColor: fehlt. Der Standardinitialisierer hat keine Standardwerte. –

+0

Und das andere Problem ist, dass Sie sich auf Standard-Initialisierer verlassen, der ALLE Eigenschaften enthält. Fügen Sie textColor hinzu, oder schreiben Sie Ihren eigenen Initialisierer. –

Antwort

2

Es gibt zwei Probleme:

  • Argumente als selected: ... übergeben werden, nicht selected = ....
  • Es gibt nur einen Standardwert memberwise Initialisierer, der alle Eigenschaften als Argumente verwendet.

So würde dies kompilieren:

var settingsItem = SettingsItem(title: "Title", 
           textColor: #colorLiteral(red: 0, green: 0, blue: 0, alpha: 1), 
           selected: { return true }, 
           action: {}) 

Wenn Sie eine benutzerdefinierte Initialisierung mit Standardargument definieren Werte

struct SettingsItem { 
    let title: String 
    let textColor: UIColor 
    let selected:() -> Bool 
    let action:() -> Void 

    init(title: String, 
     textColor: UIColor = #colorLiteral(red: 0, green: 0, blue: 0, alpha: 1), 
     selected: @escaping() -> Bool = { return false }, 
     action: @escaping() -> Void = { }) 
    { 
     self.title = title 
     self.textColor = textColor 
     self.selected = selected 
     self.action = action 
    } 
} 

dann die entsprechenden Argumente optional sind, zum Beispiel:

let settingsItem = SettingsItem(title: "Title", selected: { return true }) 
+0

Diese Verschlüsse sind nicht flüchtig, so dass @escaping nicht notwendig ist. –

+0

Ahh ja das Gleiche statt des Doppelpunktes. Manchmal ist die Lösung nur so offensichtlich. Wenn ich das Problem mit fehlenden Argumenten behoben habe, füge ich zusätzliche Initialisierer hinzu, um das zu berücksichtigen. – colincameron

+0

@MichaelBernat: Sie entkommen, und das Schlüsselwort ist notwendig (sonst beschwert sich der Compiler). Vergleichen Sie https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Closures.html#//apple_ref/doc/uid/TP40014097-CH11-ID546: * "Eine Möglichkeit, wie eine Schließung entkommen kann wird in einer Variablen gespeichert, die außerhalb der Funktion definiert ist ... "* –

0

Argumente auf diese Weise übergeben sho uld Arbeit für Sie

var settingsItem = SettingsItem(title: "Title", textColor: UIColor.red, selected: {() -> Bool in 
    return true 
}) { 
    return 
} 
1

Sie haben für struct benutzerdefinierte Init-Methode definieren

versuchen, diese

struct SettingsItem { 
    var title: String = "" 
    var textColor: UIColor = #colorLiteral(red: 0, green: 0, blue: 0, alpha: 1) 
    var selected:() -> Bool = { return false } 
    var action:() -> Void = { } 

    init(title: String, textColor: UIColor, selected: @escaping() -> Bool, action: @escaping() -> Void) { 
     self.title = title 
     self.textColor = textColor 
     self.selected = selected 
     self.action = action 
    } 
} 

und Sie dieses

SettingsItem(title: "title", textColor: .red, selected: {() -> Bool in 
     code ... 
    }) { 
     code ... 
}