0Pricing
Learn Rust Coding · Lekcja

Własne iteratory

Implementowanie Iterator

Własne iteratory to bezpłatna lekcja Learn Rust Coding na CoddyKit. To lekcja 4 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 Learn Rust Coding, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Learn Rust Coding zawiera 4 lekcji w sumie.

Utwórz własny iterator

Nie trzeba ograniczać się do wbudowanych iteratorów. Po zaimplementowaniu cechy Iterator dla własnego typu zyskuje on wszystkie adaptery i konsumentów bez dodatkowej pracy.

Wystarczy dostarczyć typ Item oraz metodę next.

Struktura licznika

Rozpocznij od struktury przechowującej stan iteratora. Prosty licznik potrzebuje tylko bieżącej wartości.

struct Counter {
    count: u32,
}

fn main() {
    let c = Counter { count: 0 };
    println!("start at {}", c.count);
}

Implementowanie next

Zaimplementuj Iterator dla struktury. Ustaw type Item, a następnie napisz next, aby aktualizowała stan i zwracała Some aż do wystąpienia warunku zakończenia, po czym zwróciła None.

struct Counter { count: u32 }

impl Iterator for Counter {
    type Item = u32;
    fn next(&mut self) -> Option<u32> {
        if self.count < 5 {
            self.count += 1;
            Some(self.count)
        } else {
            None
        }
    }
}

fn main() {
    let mut c = Counter { count: 0 };
    println!("{:?}", c.next());
    println!("{:?}", c.next());
}

Używanie w pętli for

Gdy istnieje next, własny typ działa w pętli for tak jak każdy standardowy iterator.

struct Counter { count: u32 }

impl Iterator for Counter {
    type Item = u32;
    fn next(&mut self) -> Option<u32> {
        if self.count < 5 { self.count += 1; Some(self.count) } else { None }
    }
}

fn main() {
    for n in (Counter { count: 0 }) {
        print!("{} ", n);
    }
    println!();
}

Darmowe adaptery i konsumenci

Po zaimplementowaniu jednej metody dostępny jest cały zestaw narzędzi iteratorów. W tym przykładzie sumujemy kwadraty sparowanych wartości licznika.

struct Counter { count: u32 }

impl Iterator for Counter {
    type Item = u32;
    fn next(&mut self) -> Option<u32> {
        if self.count < 5 { self.count += 1; Some(self.count) } else { None }
    }
}

fn main() {
    let total: u32 = Counter { count: 0 }.map(|x| x * 2).sum();
    println!("{}", total);
}

Metoda konstruktora

Dodaj funkcję new, aby użytkownicy nie musieli odwoływać się bezpośrednio do pól wewnętrznych. To czytelniejsze rozwiązanie pozwalające zachować prywatność pola.

struct Counter { count: u32 }

impl Counter {
    fn new() -> Counter { Counter { count: 0 } }
}

impl Iterator for Counter {
    type Item = u32;
    fn next(&mut self) -> Option<u32> {
        if self.count < 3 { self.count += 1; Some(self.count) } else { None }
    }
}

fn main() {
    let v: Vec<u32> = Counter::new().collect();
    println!("{:?}", v);
}

Iterator Fibonacciego

Iteratory mogą przechowywać bardziej złożony stan. Generator Fibonacciego pamięta dwie ostatnie wartości i aktualizuje je przy każdym wywołaniu next.

struct Fib { a: u64, b: u64 }

impl Iterator for Fib {
    type Item = u64;
    fn next(&mut self) -> Option<u64> {
        let current = self.a;
        self.a = self.b;
        self.b = current + self.b;
        Some(current)
    }
}

fn main() {
    let fib = Fib { a: 0, b: 1 };
    let seq: Vec<u64> = fib.take(8).collect();
    println!("{:?}", seq);
}

Nieskończone iteratory są w porządku

Iterator Fibonacciego nigdy nie zwraca None — jest nieskończony. Jest to bezpieczne, ponieważ leniwe działanie oznacza, że wartości są tworzone dopiero na żądanie. Użyj take, aby ograniczyć jego długość.

struct Fib { a: u64, b: u64 }

impl Iterator for Fib {
    type Item = u64;
    fn next(&mut self) -> Option<u64> {
        let c = self.a;
        self.a = self.b;
        self.b = c + self.b;
        Some(c)
    }
}

fn main() {
    let big = Fib { a: 0, b: 1 }.nth(20);
    println!("{:?}", big);
}

Iterowanie po typie opakowującym

Często implementuje się Iterator dla pomocniczej struktury, która pożycza dane. W tym przykładzie iterator stepper zwraca co drugą liczbę z przechowywanego w środku zakresu.

struct EvenUpTo { current: u32, max: u32 }

impl Iterator for EvenUpTo {
    type Item = u32;
    fn next(&mut self) -> Option<u32> {
        if self.current > self.max { return None; }
        let value = self.current;
        self.current += 2;
        Some(value)
    }
}

fn main() {
    let evens: Vec<u32> = (EvenUpTo { current: 0, max: 10 }).collect();
    println!("{:?}", evens);
}

Dlaczego tworzyć własne iteratory?

Własne iteratory pozwalają przesyłać wartości bez alokowania całej kolekcji, modelować nieskończone lub obliczane sekwencje oraz udostępniać wywołującym znany, komponowalny interfejs.

Jedna niewielka metoda next otwiera dostęp do całego ekosystemu.

Wskazówki projektowe

Ogranicz stan do minimum, zwracaj None dokładnie raz na końcu (lub nigdy w przypadku iteratorów nieskończonych) i unikaj kosztownych operacji wewnątrz next, aby leniwe działanie pozostało tanie.

Szybkie sprawdzenie

Implementowanie cechy Iterator.

Podsumowanie

Utworzono własne iteratory:

  • Przechowuj stan w strukturze, a następnie użyj impl Iterator
  • Zdefiniuj type Item i napisz next
  • Natychmiast otrzymujesz adaptery i konsumentów bez dodatkowej pracy
  • Iteratory mogą być skończone lub nieskończone; użyj take, aby ograniczyć nieskończone

Często zadawane pytania

Czy lekcja „Własne iteratory” jest bezpłatna?

Tak — pełny tekst „Własne iteratory” 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 Learn Rust Coding, przejdź na CoddyKit PRO. Kurs Learn Rust Coding zawiera 4 lekcji w sumie.

Co nauczysz się w „Własne iteratory”?

Implementowanie Iterator Ćwiczysz Learn Rust Coding 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ąć Learn Rust Coding?

Nie wymagamy żadnego doświadczenia. Learn Rust Coding 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 4 z 4.

Ile czasu zajmuje lekcja „Własne iteratory”?

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 Learn Rust Coding?

Tak. Każda lekcja Learn Rust Coding 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.

Wszystkie lekcje w tym kursie

  1. Cecha Iterator
  2. map, filter, collect
  3. Adaptery i konsumenci
  4. Własne iteratory
← Powrót do Learn Rust Coding