Swift: die Wiederverwendung einer Schließung definition (mit typealias)
Ich versuche zu tun, erstellen eine Schließung Definitionen, die ich bin gonna verwenden eine Menge in meiner iOS-app. So dachte ich, ein typealias wie es schien die vielversprechendste ...
Habe ich einen kleinen Spielplatz Beispiel, das zeigt mein Problem im detail
//Here are two tries for the Closure I need
typealias AnonymousCheck = (Int) -> Bool
typealias NamedCheck = (number: Int) -> Bool
//This works fine
var var1: AnonymousCheck = {
return $0 > 0
}
var1(-2)
var1(3343)
//This works fine
var var2: NamedCheck = {
return $0 > 0
}
var2(number: -2)
var2(number: 12)
//But I want to use the typealias mainly as function parameter!
//So:
//Use typealias as function parameter
func NamedFunction(closure: NamedCheck) {
closure(number: 3)
}
func AnonymousFunction(closure: AnonymousCheck) {
closure(3)
}
//This works as well
//But why write again the typealias declaration?
AnonymousFunction({(another: Int) -> Bool in return another < 0})
NamedFunction({(another: Int) -> Bool in return another < 0})
//This is what I want... which doesn't work
//ERROR: Use of unresolved identifier 'number'
NamedFunction({NamedCheck in return number < 0})
//Not even these work
//ERROR for both: Anonymous closure arguments cannot be used inside a closure that has exlicit arguments
NamedFunction({NamedCheck in return $0 < 0})
AnonymousFunction({AnonymousCheck in return $0 < 0})
Bin ich etwas fehlt oder es einfach nicht unterstützt Swift?
Dank
EDIT/ERGÄNZUNG:
Das oben ist nur ein einfaches Beispiel. Im realen Leben meine typealias ist komplizierter. So etwas wie:
typealias RealLifeClosure = (number: Int, factor: NSDecimalNumber!, key: String, upperCase: Bool) -> NSAttributedString
Ich im Grunde verwenden möchten typealias als Verknüpfung, so dass ich nicht geben, dass viel. Vielleicht typealias ist nicht die richtige Wahl... gibt es eine andere?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Sind Sie nicht umschreiben der
typealias
Erklärung in diesem code sind Sie der Deklaration der Parameter und Rückgabetyp:Glücklich, Swift, Typ-Inferenz, können Sie eine der folgenden Optionen verwenden - wählen Sie den Stil, die am besten fühlt sich für Sie:
number
undInt
imlet number: Int = 3
.{ number, factor, key in ... }
als sich auf Namen, die an anderer Stelle definierten) es ist nicht so schlimm.{ number, _, _, _ in ... }
.Ich glaube nicht, dass Sie werde in der Lage sein, das zu tun, was Sie wollen. Zur Vereinfachung Ihrer Beispiel etwas, können Sie dies tun:
Aber Sie können nicht tun, was Sie wollen, und das ist auf die Tatsache stützen, dass das Tupel arg aufgerufen wird
number
zu finden, um es innerhalb der Schließung, ohne es als Teil der Schließung:Beachten Sie, dass Sie können die Namen der parameter, ohne dass eine Art (die abgeleitet ist von der Art der
g
):aber auch, man kann es nennen, was Sie wollen:
Hier ist was ich denke passiert ist (dies ist zum Teil Spekulation). Denken Sie daran, wie Funktionen können externen und internen argument-Namen:
Oder, um es zu schreiben longhand:
Aber Sie können auch als die zweite, innere, name, was auch immer Sie mögen:
Ich denke, das ist, was passiert mit den Verschlüssen mit benannten Tupel. Die "externen" name "Nummer", aber Sie muss es geben, einen "internen" Namen, das ist, was Sie verwenden müssen, die in der Funktion Körper. Sie können nicht machen, verwenden Sie das externe argument innerhalb der Funktion. Im Falle der Schließung Ausdrücke, wenn Sie nicht geben Sie einen internen Namen, die Sie verwenden können
$0
etc, aber kann man nicht einfach überspringen, mehr, als Sie können überspringen Sie den internen Namen ganz und ausschließlich auf den externen Namen bei der Definition einer regulären Funktion.Ich hatte gehofft, dass ich beweisen könnte, diese Theorie durch Folgendes:
was in
f
Typ(a: Int, b: Int)->Bool)
. Dies stellt, wie:aber es sieht nicht wie die externen Namen für das argument machen es sich die Art der
f
oderg
.Die syntax zum erstellen einer Schließung ist:
Was auf der linken Seite der
in
ist der Verschluss Signatur (Parameter und Rückgabewert). In einigen Fällen kann die Signatur weggelassen werden, oder vereinfacht, wenn Typ-Inferenz ist in der Lage, um zu bestimmen, die Anzahl der Parameter und Ihr Typ, und der Rückgabewert.In Ihrem Fall es nicht funktioniert, weil Sie auf der Durchreise sind eine Art alias, aber es wird so ausgelegt, dass Sie einen parameter name. Die 3 Zeilen funktionieren, wenn Sie entweder:
Namen der parameter richtig
verwenden Sie die Kurzform Argumente:
verwenden Sie die Kurzform Argumente und impliziter return: