Ich möchte eine benutzerdefinierte iterierbare Klasse implementieren, die nil-Elemente enthalten kann, ähnlich wie [Any?]
. Die Übereinstimmung mit SequenceType funktioniert meistens, außer der Vertrag von GeneratorType.next()
sagt, er sollte nil zurückgeben, wenn alle Elemente erschöpft sind. Gibt es eine Problemumgehung?
Hier ist ein (ziemlich albernes) Beispiel:
%Vor%Ausgabe:
%Vor% Der Generator gibt ein optionales Element (das Optional(nil)
sein kann) für jedes Element zurück,
und nil
, wenn die Sequenz erschöpft ist.
Siehe auch "Optionals-Fallstudie: valuesForKeys" im Swift-Blog über den Unterschied zwischen nil
und
Optional(nil)
und seine Anwendungen.
Update für Swift 2:
%Vor% Es ist möglich, SequenceType
protokollkonforme Objekte zu erzeugen, die Optional
s zurückgeben. Da es jedoch leicht sein kann, Fehler zu machen, müssen Sie sehr vorsichtig sein, wenn Sie Ihr next()
Methode (mit einem benutzerdefinierten GeneratorType
Protokoll konforme Objekt) oder bei der Implementierung Ihrer anyGenerator(_:)
Schließungsparameter (mit AnyGenerator
).
Als Faustregel sollten Sie immer diesem Muster folgen:
Wenn Sie ein benutzerdefiniertes
GeneratorType
protokollkonformes Objekt verwenden und möchten, dass esInt?
zurückgibt, müssen Sie den Rückgabetyp Ihrernext()
-Methode aufInt??
setzen.Wenn Sie eine
AnyGenerator
-Instanz verwenden und möchten, dassInt?
(AnyGenerator<Int?>
) zurückgegeben wird, müssen Sie eine Schließung vom Typ() -> Int??
an IhreanyGenerator
-Methode übergeben.
Der folgende Playground-Code, der von @Martin Rs Antwort inspiriert wurde, zeigt, wie ein SequenceType
Protokoll konform Struct
mit einer benutzerdefinierten GeneratorType
protokollkonformen Struktur implementiert werden kann, die Optional
s zurückgibt:
Beachten Sie, dass wenn Sie return i % 2 == 0 ? i : Optional<Int>.None
im vorherigen Code durch return i % 2 == 0 ? i : Optional.None
ersetzen, Ihre for-Schleife nichts ausgibt und Ihr Array leer ist.
Beachten Sie auch, dass Sie, wenn Sie return Int??.None
im vorherigen Code durch return Int?.None
ersetzen, eine Endlosschleife von nil
erzeugen.
AnyGenerator
Der folgende Playground-Code zeigt, wie man SequenceType
protokollkonforme Struct
mit einer AnyGenerator
-Instanz, die Optional
elements zurückgibt, sehr vorsichtig umsetzt:
Die vorherige Sequenz kann in einem sehr übersichtlichen, aber weniger weniger sicheren Stil umgeschrieben werden:
%Vor%Tags und Links swift