Ich habe eine schwere Zeit, den Unterschied zwischen rest
und next
in Clojure zu verstehen. The official site's page on laziness gibt an, dass die Präferenz wahrscheinlich rest
sein sollte, aber es erklärt nicht wirklich den Unterschied zwischen den beiden. Kann jemand Einblick geben?Clojure: Rest gegen nächste
Antwort
Als Seite, die Sie beschrieben verknüpft, next
ist strenger als (das neue Verhalten) rest
, weil es die Struktur der faulen Nachteile bewerten muss zu wissen, ob nil
oder seq zurückzukehren.
rest
auf der anderen Seite gibt immer eine seq, so dass nichts ausgewertet werden muss, bis Sie tatsächlich das Ergebnis rest
verwenden. Mit anderen Worten, rest
ist fauler als next
.
OK, ich denke, ich verstehe vielleicht, was du meinst. Willst du damit sagen, dass 'next' immer eine zurückgibt? cons cell, während "rest" lediglich einen ISeq (oder welchen Typ auch immer es ist) zurückgibt? –
@Daniel: 'next' gibt' nil' oder einen nicht leeren 'seq' zurück.' rest' gibt immer einen 'seq' zurück, – sepp2k
Also nehme ich an, dass es für einige Sequenzen eine teure Operation ist, festzustellen, ob es mehr Elemente gibt.Mit einer normalen Liste von Cons-Zellen würde ich denken, dass es trivial ist zu bestimmen, ob Sie das Ende erreicht haben Die Liste könnte jedoch mit einer trägen Sequenz (aus Lazy-Seq, vielleicht), diese Bestimmung teuer sein verstand nicht ganz, dass sich nil von der leeren Sequenz unterschied. Es hört sich so an, als ob Subsequenzen mit Rest zu schwächeren Garantien führen und daher effizienter sein können. –
Es ist einfach, wenn Sie diese haben:
(next '(1))
=> nil
So next
bei der nächsten Sache sieht und wenn die Linie kehrt nil
anstelle eines leeren seq leer. Das bedeutet, dass es nach vorne schauen muss (zum ersten Punkt, den es zurückgeben würde), was es nicht völlig faul macht (vielleicht brauchen Sie den nächsten Wert nicht, aber next
verschwendet die Rechenzeit, um nach vorne zu schauen).
(rest '(1))
=>()
rest
sieht nicht voraus und gibt nur den Rest der Seq.
Vielleicht denken Sie, warum hier sogar zwei verschiedene Dinge zu verwenden? Der Grund ist, dass Sie normalerweise wissen möchten, ob nichts mehr im Seq ist und geben Sie einfach nil
zurück, aber in einigen Fällen, in denen die Leistung sehr wichtig ist und die Auswertung eines weiteren Elements eine enorme Anstrengung bedeuten kann, können Sie rest
verwenden.
nur um es zu Tode zu schlagen: (Rest nil) =>() – gtrak
next
ist wie (seq (rest ...))
.
rest
wird das verbleibende Stück einer Sequenz zurückgeben. Wenn dieses Stück der Sequenz noch nicht realisiert wurde, erzwingt rest
es nicht. Es wird dir nicht einmal sagen, ob noch mehr Elemente in der Sequenz übrig sind.
next
macht das gleiche aber zwingt dann mindestens ein Element der Sequenz zu realisieren. Wenn also next
nil
zurückgibt, wissen Sie, dass in der Sequenz keine Elemente mehr vorhanden sind.
Ich ziehe jetzt next
mit reursion zu verwenden, da die Escape-Auswertung einfacher/Reiniger ist:
(loop [lst a-list]
(when lst
(recur (next lst))
vs
(loop [lst a-list]
(when-not (empty? lst) ;; or (when (seq? lst)
(recur (rest lst))
Ein Fall für rest
verwendet wird, wäre aber, wenn Sie Verwenden Sie eine Sammlung als Warteschlange oder Stapel. In diesem Fall möchten Sie, dass Ihre Funktion eine leere Sammlung zurückgibt, wenn Sie den letzten Eintrag puffern oder aus der Warteschlange entfernen.
- 1. Clojure: reduzieren gegen anwenden
- 2. Clojure^schwimmt gegen #^schwimmt?
- 3. Rest gegen Seife. Hat REST eine bessere Leistung?
- 4. Clojure Leistung wirklich schlecht auf einfache Schleife gegen Java
- 5. Wie nur die * nächste * .class oder div (nicht der Rest)
- 6. Authentifizierung von Android Gerät gegen Spring Security Rest API
- 7. Kristallraum gegen Irrlicht gegen .....?
- 8. Clojure Koaleszenzfunktion
- 9. Nächste N nächste Geo-Punkte
- 10. Mysql Abfrage gegen Wildcard
- 11. Komplexe Datenmanipulation in Clojure
- 12. Bootstrap: Nächste Schaltfläche sollte nächste Registerkarte anzeigen
- 13. Flickr API Java/Clojure
- 14. Jedes Beispiel, in dem Clojure wirklich gegen Java glänzt, die nicht Parallelität/Unveränderlichkeit-Feature verwandt ist?
- 15. Akka Kill gegen Stop gegen Giftpille?
- 16. @synchronized gegen NSLock Instanz gegen pthread_mutex_t
- 17. Clojure recur seltsame Verhalten
- 18. Clojure anwenden vs Karte
- 19. REST und große Datenbankabfragen
- 20. faul Neuimplementierung von Clojure Verschachtelung
- 21. clojure oauth und credentials
- 22. Verschachtelung von # /% in clojure Makros
- 23. Lein Clojure 1.3 vs Clojure 1.2.1
- 24. GC.KeepAlive gegen
- 25. Clojure, wenn ein Apostroph erforderlich, bevor Vektor
- 26. Neudefinition von "def" in Clojure
- 27. Clojure Worksheets
- 28. Clojure Endlosschleife
- 29. Clojure: = vs ==
- 30. Clojure macroexpand
Dieser Punkt ist keine separate Antwort wert: Was die Antworten bisher nicht vollständig explizit gemacht haben, ist, dass '()' wahr ist, während 'nil' falsch ist. So '(defn weitergehen [my-coll] (if (rest my-coll) (weitermachen (Rest my-coll)) "Beendet.")' wird für immer weitergehen - oder vielmehr, wird den Stapel überlaufen - während '(defn fortfahren [my-coll] (if (next my-coll) (weitermachen (next my-coll))" Beendet. ")" Wird beendet. (OP hat das sicher herausgefunden; ich füge diese Bemerkung für andere hinzu.) – Mars