Budowanie LazyList
Utworzy Pan/Pani leniwe sekwencje.
Budowanie LazyList to bezpłatna lekcja Scala for Backend Engineering & Functional Programming na CoddyKit. To lekcja 2 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Scala for Backend Engineering & Functional Programming, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Scala for Backend Engineering & Functional Programming zawiera 4 lekcji w sumie.
Podstawy tworzenia
Istnieje kilka sposobów tworzenia obiektu LazyList. Najprostszy to fabryka apply, podobnie jak przy tworzeniu List.
Prawdziwa siła tkwi jednak w konstruktorach, które zachowują leniwość ogona — omówimy je w tej lekcji.
val ll = LazyList(10, 20, 30)
println(ll.head)Pusta LazyList
LazyList.empty jest terminatorem, czyli leniwym odpowiednikiem Nil. Każda skończona LazyList kończy się tą wartością.
Używa się jej jako przypadku bazowego podczas dodawania elementów na początku za pomocą #::.
object Demo extends App {
val empty = LazyList.empty[Int]
println(empty.isEmpty)
println(empty.toList)
}Dodawanie na początku za pomocą #::
Operator #:: dodaje głowę do ogona przekazywanego by-name. Listę należy budować od prawej do lewej, kończąc ją za pomocą LazyList.empty.
Ponieważ #:: przyjmuje ogon leniwie, nic poza głową nie jest tworzone, dopóki nie zostanie wymuszone.
object Demo extends App {
val ll = 1 #:: 2 #:: 3 #:: LazyList.empty
println(ll.toList)
}Obserwowanie leniwej ewaluacji
Proszę umieścić efekt uboczny w ogonie, aby zobaczyć, kiedy zostanie wykonany. Dopiero wymuszenie ogona go uruchamia.
Proszę uruchomić ten przykład: „building tail” jest wypisywane dopiero po uzyskaniu dostępu do drugiego elementu, a nie podczas definiowania LazyList.
object Demo extends App {
val ll = 1 #:: { println("building tail"); 2 #:: LazyList.empty }
println("defined")
println(ll.head)
println(ll(1))
}Jawne użycie cons
Wewnętrznie #:: jest metodą LazyList.cons. W metodzie cons zarówno głowa, jak i ogon są przekazywane by-name, co zapewnia pełną kontrolę nad ewaluacją.
Jest to przydatne podczas definiowania generatorów rekurencyjnych.
val ll = LazyList.cons(1, LazyList.cons(2, LazyList.empty))
println(ll.head)Generatory rekurencyjne
LazyList może odwoływać się do samej siebie. Należy zdefiniować funkcję, która tworzy głowę i rekurencyjnie wywołuje samą siebie dla ogona.
Ponieważ ogon jest przekazywany by-name, rekurencja nie wykonuje się bez końca — zostaje wstrzymana do momentu zażądania każdej kolejnej komórki.
def countFrom(n: Int): LazyList[Int] =
n #:: countFrom(n + 1)
println(countFrom(5).take(3).toList)Uruchamianie generatora
Uruchommy generator odwołujący się do samego siebie i pobierzmy kilka wartości. take ogranicza liczbę wymuszanych komórek.
Bez take działanie trwałoby bez końca, dlatego przed wymuszeniem nieskończonego generatora zawsze należy ograniczyć jego zakres.
object Demo extends App {
def countFrom(n: Int): LazyList[Int] =
n #:: countFrom(n + 1)
println(countFrom(1).take(5).toList)
}Z iteratora
Można opakować istniejącą kolekcję lub iterator. LazyList.from(start) tworzy nieskończony ciąg liczbowy, a someList.to(LazyList) konwertuje dane, które są już znane.
Pozwala to uzyskać leniwy widok danych, które już Państwo posiadają lub potrafią opisać.
object Demo extends App {
val ll = List(1, 2, 3).to(LazyList)
println(ll.map(_ * 2).toList)
}LazyList.iterate
LazyList.iterate(seed)(f) wielokrotnie stosuje f, aby utworzyć każdy kolejny element na podstawie poprzedniego.
To przejrzysty sposób wyrażania sekwencji definiowanych regułą przejścia, takich jak kolejne potęgi liczby dwa.
object Demo extends App {
val powers = LazyList.iterate(1)(_ * 2)
println(powers.take(6).toList)
}LazyList.continually
LazyList.continually(expr) bez końca powtarza wyrażenie, obliczając je ponownie dla każdego elementu. Jest przydatne w przypadku strumieni stałych lub losowych wartości.
W połączeniu z take pozwala pobrać skończony fragment.
object Demo extends App {
val zeros = LazyList.continually(0)
println(zeros.take(4).toList)
}Wybór konstruktora
Proszę użyć apply dla małych, ustalonych list, #:: lub cons dla ręcznie zapisywanej rekurencji, iterate dla reguł przejścia, from do zliczania, a continually do powtarzania.
Wszystkie te konstrukcje zachowują leniwość ogona, więc wybór zależy od przejrzystości zapisu.
Szybkie sprawdzenie
Proszę sprawdzić, jak dobrze rozumieją Państwo tworzenie LazyList.
Podsumowanie
Utworzyli Państwo LazyList za pomocą apply, empty, #::/cons, iterate, from i continually.
Ogon przekazywany by-name sprawia, że samoodwołujące się, potencjalnie nieskończone generatory można bezpiecznie definiować. Następnie wykorzystamy tę właściwość do tworzenia naprawdę nieskończonych strumieni.
Często zadawane pytania
Czy lekcja „Budowanie LazyList” jest bezpłatna?
Tak — pełny tekst „Budowanie LazyList” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Scala for Backend Engineering & Functional Programming, przejdź na CoddyKit PRO. Kurs Scala for Backend Engineering & Functional Programming zawiera 4 lekcji w sumie.
Co nauczysz się w „Budowanie LazyList”?
Utworzy Pan/Pani leniwe sekwencje. Ćwiczysz Scala for Backend Engineering & Functional Programming z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć Scala for Backend Engineering & Functional Programming?
Nie wymagamy żadnego doświadczenia. Scala for Backend Engineering & Functional Programming w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 2 z 4.
Ile czasu zajmuje lekcja „Budowanie LazyList”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji Scala for Backend Engineering & Functional Programming?
Tak. Każda lekcja Scala for Backend Engineering & Functional Programming zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.