Kann mir jemand erklären, warum der letzte Fall in diesem Beispiel ein Kompilierungsfehler ist?Generische Funktionen und Unterklassen. Kann jemand diesen Kompilierungsfehler erklären?
class A{}
class B: A{}
protocol Finder{
func find< T: A>(_ f: (T)->Bool) -> T?
}
class FinderImpl : Finder{
func find<T : A>(_ f: (T) -> Bool) -> T? {
//In the real code I use T to find the instance. I.e. CoreData
return nil
}
}
let finder = FinderImpl()
//OK
let optionalB : B? = finder.find{_ in true}
let a : A = finder.find{_ in true}!
let b : B = finder.find{(b: B) in true}!
//Compile Error
let b2 : B = finder.find{_ in true}!
lassen a. Der Compiler verwendet (A) -> Bool.
als den Schließungstyp. Dann ist der Rückgabetyp A.
lassen b. Dies wird kompiliert, da der Verschluss explizite Informationen enthält: (B)->Bool
lassen Sie optionalB. Ich frage mich, warum dieser Fall funktioniert, hier hat die Schließung auch keine Informationen. Der Unterschied ist die ! operator
Der Fehler: Im letzten Fall wird der Compiler übergeben, die Art des Verschlusses zu schließen, versagt finden Func. Es schlägt mir vor, as! B
zu werfen, weil es denkt, dass der Verschlusstyp (A)->Bool
ist. Es wird nicht mit den Referenztyp von b2 B.
Wichtig: ich nicht as! B
werfen kann, weil ich die Suchfunktion benötigen tatsächlich den Typ B zu verwenden, wenn ich as! B
werfen, wird die Funktion des Typs A verwenden und erhalten die falsche Instanz. Der Code würde kompilieren, aber die Ergebnisse wären falsch.
Wenn ich die T:A
Einschränkung entfernen, gibt es keinen Kompilierungsfehler.
Das sieht für mich wie ein Compiler-Fehler aus. Ich denke, der Compiler sollte den Typ von b2 verwenden, um zu wissen, dass der Abschluss (B)->Bool
und dann der Ergebnistyp von Find ist. Die T:A
Einschränkung und das Fehlen von Typinformationen in der Schließung führt dazu, dass es fehlschlägt.
Fehle ich hier etwas? Irgendwelche Gedanken?
Hallo, Danke für Ihre Antwort. Ich verstehe Ihre Punkte, ich denke, ich habe das auch in der Frage erwähnt. Was ich als ein Problem sehe, ist, dass ich in b2: B tatsächlich die Typinformation spezifiziere. T = B. Ich sehe nicht, warum es notwendig wäre, (B) -> Bool auch explizit anzugeben. Nimm zum Beispiel das optionale B, dort gebe ich nicht den Schließungstyp an, aber es funktioniert. Deshalb denke ich, dass dies ein Compiler Bug sein könnte. Irgendwelche Gedanken? – Lio