0Pricing
Go Academy · Lekcja

Etapy potoku

Łącz etapy kanałami

Etapy potoku to bezpłatna lekcja Go Academy na CoddyKit. To lekcja 3 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 Go Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Go Academy zawiera 4 lekcji w sumie.

Czym jest potok

Potok to seria etapów połączonych kanałami. Każdy etap odbiera wartości, wykonuje pracę i wysyła wyniki do kolejnego etapu. Dane przepływają jak na linii montażowej.

  • Każdy etap jest goroutine
  • Etapy komunikują się wyłącznie za pośrednictwem kanałów
  • Potoki można łatwo łączyć i analizować

Konwencja sygnatury etapu

Zgodnie z konwencją każdy etap przyjmuje co najmniej jeden kanał wejściowy tylko do odczytu i zwraca kanał wyjściowy tylko do odczytu. Dzięki temu etapy można łączyć w łańcuch.

func stage(in <-chan int) <-chan int {
    out := make(chan int)
    go func() {
        defer close(out)
        for v := range in {
            out <- v
        }
    }()
    return out
}

Etap źródłowy

Pierwszy etap generuje dane. Często przyjmuje slice lub argumenty variadic i przesyła je strumieniowo do kanału.

func numbers(vals ...int) <-chan int {
    out := make(chan int)
    go func() {
        defer close(out)
        for _, v := range vals {
            out <- v
        }
    }()
    return out
}

Etap transformacji

Ten etap mnoży każdą wartość przez dziesięć. Odczytuje dane z in i zapisuje przekształconą wartość do out.

func tenfold(in <-chan int) <-chan int {
    out := make(chan int)
    go func() {
        defer close(out)
        for v := range in {
            out <- v * 10
        }
    }()
    return out
}

Etap filtrowania

Filtr przekazuje dalej tylko wartości spełniające określony warunek. W tym przykładzie zachowujemy liczby parzyste, a pozostałe odrzucamy.

func evens(in <-chan int) <-chan int {
    out := make(chan int)
    go func() {
        defer close(out)
        for v := range in {
            if v%2 == 0 {
                out <- v
            }
        }
    }()
    return out
}

Łączenie etapów

Etapy można łączyć, przekazując wyjście jednego jako wejście kolejnego. Taki łańcuch można niemal odczytać jak zdanie.

pipe := tenfold(evens(numbers(1, 2, 3, 4)))
for v := range pipe {
    fmt.Println(v)
}

defer close(out)

Użycie defer close(out) gwarantuje zamknięcie kanału wyjściowego po zakończeniu goroutine etapu, nawet jeśli później zostaną dodane wcześniejsze instrukcje return. Dzięki temu sygnał końca strumienia jest przekazywany dalej.

Kompletny potok

Najpierw źródło, następnie filtr, a na końcu transformacja. Uruchom program, aby zobaczyć wartości parzyste pomnożone przez dziesięć.

package main

import "fmt"

func numbers(vals ...int) <-chan int {
    out := make(chan int)
    go func() { defer close(out); for _, v := range vals { out <- v } }()
    return out
}

func evens(in <-chan int) <-chan int {
    out := make(chan int)
    go func() { defer close(out); for v := range in { if v%2 == 0 { out <- v } } }()
    return out
}

func tenfold(in <-chan int) <-chan int {
    out := make(chan int)
    go func() { defer close(out); for v := range in { out <- v * 10 } }()
    return out
}

func main() {
    for v := range tenfold(evens(numbers(1, 2, 3, 4, 5, 6))) {
        fmt.Println(v)
    }
}

Strumieniowanie zamiast przetwarzania partiami

Wartości przepływają przez potok pojedynczo, w miarę ich tworzenia. Etap transformacji może rozpocząć pracę nad pierwszym elementem, zanim źródło wyemituje ostatni. Pozwala to ograniczyć zużycie pamięci i opóźnienie.

Potoki są leniwe

Etap nie wykonuje żadnej pracy, dopóki coś nie odczyta jego wyjścia. Jeśli odbiorca przestanie wykonywać range, etapy nadrzędne blokują się podczas wysyłania danych. Ten naturalny mechanizm backpressure zapobiega niepotrzebnym obliczeniom.

Dodawanie współbieżności

Aby przyspieszyć wolny etap, należy utworzyć wiele jego instancji odczytujących dane z tego samego wejścia i połączyć ich wyjścia. Sygnatura etapu pozostaje taka sama — zmienia się tylko sposób połączenia elementów.

Szybki test

Proszę sprawdzić zrozumienie potoków.

Podsumowanie

Poznali Państwo etapy potoku:

  • Każdy etap: wejście tylko do odczytu i wyjście tylko do odczytu
  • defer close(out) przekazuje sygnał końca strumienia
  • Etapy można łączyć przez zagnieżdżanie wywołań
  • Potoki przetwarzają dane leniwie i zapewniają backpressure

Często zadawane pytania

Czy lekcja „Etapy potoku” jest bezpłatna?

Tak — pełny tekst „Etapy potoku” 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 Go Academy, przejdź na CoddyKit PRO. Kurs Go Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „Etapy potoku”?

Łącz etapy kanałami Ćwiczysz Go Academy 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ąć Go Academy?

Nie wymagamy żadnego doświadczenia. Go Academy 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 3 z 4.

Ile czasu zajmuje lekcja „Etapy potoku”?

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 Go Academy?

Tak. Każda lekcja Go Academy 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. Wzorzec puli workerów
  2. Fan-Out i Fan-In
  3. Etapy potoku
  4. Kontrolowane zamykanie
← Powrót do Go Academy