Der Weg hier ist einfach zu kompliziert und mehrdeutig. Sie können dies sehen, indem Sie Elemente löschen. Insbesondere den letzten Index fallen:
let z = [0, 1, 2].lazy.drop(while: {_ in false}).prefix(2)
In dieser Konfiguration will der Compiler z
als LazyPrefixCollection<LazyDropWhileBidirectionalCollection<[Int]>>
eingeben. Aber das ist nicht durch ganze Zahlen indexierbar.
Ich weiß, es fühlt sich an wie es sein sollte, aber es ist nicht durch den aktuellen Compiler beweisbar.
(siehe unten) Also Ihre [0]
schlägt fehl. Und Backtracking ist nicht stark genug, um aus diesem verrückten Labyrinth herauszukommen. Es gibt einfach zu viele Überladungen mit unterschiedlichen Rückgabetypen, und der Compiler weiß nicht, welche Sie wollen.
Aber dieser spezielle Fall ist trivialerweise festgelegt:
print([0, 1, 2].lazy.drop(while: {_ in false}).prefix(2).first!)
Das heißt, würde ich unbedingt vermeiden, dass die Compiler diese harte schieben. Das ist für Swift heute zu clever. Insbesondere Überladungen, die verschiedene Typen zurückgeben, sind in Swift sehr oft eine schlechte Idee. Wenn sie einfach sind, können Sie damit durchkommen. Aber wenn Sie mit dem Layern beginnen, verfügt der Compiler nicht über eine ausreichend starke Proof-Engine, um das Problem zu lösen. (Das heißt, wenn wir diese lange genug studiert, ich wette, es irgendwie tatsächlich nicht eindeutig ist, aber die Diagnose ist irreführend. Das ist eine sehr häufige Situation, wenn Sie in übermäßig klug Swift bekommen.)
Jetzt dass Sie es (in den Kommentaren) beschreiben, ist die Argumentation einfach.
LazyDropWhileCollection
kann keinen ganzzahligen Index haben. Index-Subskriptionen müssen O (1) sein. Das ist die Bedeutung von Index
im Vergleich zu anderen Indizes. (Der Index
Index muss auch den Element
Typ oder einen Absturz zurückgeben; er kann keinen Element?
zurückgeben.Das ist viel gibt es eine DictionaryIndex
die aus Key
separaten ist.)
Da die Sammlung lazy ist und eine beliebige Anzahl Elemente fehlen, Nachschlagen eine bestimmte ganze Zahl „count“ (erste, zweite, etc.) ist O (n) . Es ist nicht möglich zu wissen, was das 100. Element ist, ohne mindestens 100 Elemente durchzugehen. Um eine Sammlung zu sein, muss ihr O (1) -Index in einer Form sein, die nur erzeugt werden kann, indem die Sequenz vorher durchlaufen wurde. Es kann nicht Int
sein.
Dies ist wichtig, denn wenn man Code wie schreiben:
for i in 1...1000 { print(xs[i]) }
Sie, dass in der Größenordnung von 1000 zu erwarten „Schritten“, aber wenn diese Sammlung einen ganzzahligen Index hätte, wäre es in der Größenordnung sein von 1 Million Schritten. Indem sie den Index umhüllen, verhindern sie, dass Sie diesen Code überhaupt schreiben. Das ist besonders wichtig in hoch generischen Sprachen wie Swift, wo Schichten von Allzweckalgorithmen leicht eine unerwartete O (n) -Operation in völlig unbrauchbare Leistung kaskadieren können (mit "nicht ausführbar" meine ich Dinge, von denen man erwartet, dass sie Millisekunden dauern) Minuten oder mehr).
Der Compiler-Ausgang zeigt die zwei möglichen Kandidaten für 'faul' –
Könnten Sie bitte den entsprechenden" Problemcode "posten? – shallowThought
@shallowThought Der relevante Problemcode ist die letzte Zeile des Links im ersten Satz. Ich habe es dem obigen Beitrag hinzugefügt. –