0Pricing
Go Academy · Lekcja

Implementowanie własnych Readerów

Buduj własne strumienie

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

Tworzenie własnych strumieni

Mogą Państwo tworzyć niestandardowe źródła danych, implementując jedną metodę interfejsu io.Reader. Państwa typ będzie wtedy działać ze wszystkimi funkcjami pomocniczymi pakietu io.

Metoda do zaimplementowania

Proszę zaimplementować w swoim typie metodę Read(p []byte) (n int, err error). Należy wypełnić p, zwrócić liczbę bajtów oraz zwrócić io.EOF po zakończeniu odczytu.

Czytnik stałej wartości

Oto reader, który bez końca emituje ten sam bajt, ograniczony za pomocą LimitReader.

package main

import (
	"fmt"
	"io"
)

type constReader struct{ ch byte }

func (c constReader) Read(p []byte) (int, error) {
	for i := range p {
		p[i] = c.ch
	}
	return len(p), nil
}

func main() {
	r := io.LimitReader(constReader{ch: 'A'}, 5)
	data, _ := io.ReadAll(r)
	fmt.Println(string(data))
}

Sygnalizowanie EOF

Po wyczerpaniu źródła należy zwrócić io.EOF. Można zwrócić go osobno albo razem z ostatnimi bajtami.

package main

import (
	"fmt"
	"io"
)

type oneShot struct{ done bool }

func (o *oneShot) Read(p []byte) (int, error) {
	if o.done {
		return 0, io.EOF
	}
	o.done = true
	n := copy(p, []byte("once"))
	return n, nil
}

func main() {
	data, _ := io.ReadAll(&oneShot{})
	fmt.Println(string(data))
}

Odczytywanie z wycinka

Niestandardowy reader może śledzić pozycję w danych bazowych i zwracać fragment przy każdym wywołaniu.

package main

import (
	"fmt"
	"io"
)

type sliceReader struct {
	data []byte
	pos  int
}

func (s *sliceReader) Read(p []byte) (int, error) {
	if s.pos >= len(s.data) {
		return 0, io.EOF
	}
	n := copy(p, s.data[s.pos:])
	s.pos += n
	return n, nil
}

func main() {
	r := &sliceReader{data: []byte("custom")}
	out, _ := io.ReadAll(r)
	fmt.Println(string(out))
}

Reader przekształcający dane

Proszę opakować inny reader i przekształcać bajty w locie — tutaj każdy bajt jest zamieniany na wielką literę podczas przepływu.

package main

import (
	"bytes"
	"fmt"
	"io"
)

type upper struct{ r io.Reader }

func (u upper) Read(p []byte) (int, error) {
	n, err := u.r.Read(p)
	for i := 0; i < n; i++ {
		if p[i] >= 'a' && p[i] <= 'z' {
			p[i] -= 32
		}
	}
	return n, err
}

func main() {
	out, _ := io.ReadAll(upper{r: bytes.NewReader([]byte("hello"))})
	fmt.Println(string(out))
}

Przestrzeganie długości bufora

Nie wolno zapisywać więcej niż len(p) bajtów. Należy użyć copy(p, src), które jest ograniczone przez krótszy wycinek, i zwrócić liczbę skopiowanych bajtów.

Odbiorca wartości a odbiorca wskaźnikowy

Jeśli reader śledzi pozycję lub stan, należy użyć odbiorcy wskaźnikowego, aby zmiany zachowywały się między wywołaniami. Readery bez stanu mogą korzystać z odbiorcy wartości.

Komponowanie z funkcjami pomocniczymi io

Ponieważ Państwa typ spełnia wymagania io.Reader, można go bez dodatkowej pracy używać z io.Copy, bufio.NewReader, io.LimitReader i innymi funkcjami.

package main

import (
	"io"
	"os"
)

type dots struct{ left int }

func (d *dots) Read(p []byte) (int, error) {
	if d.left == 0 {
		return 0, io.EOF
	}
	p[0] = '.'
	d.left--
	return 1, nil
}

func main() {
	io.Copy(os.Stdout, &dots{left: 4})
	os.Stdout.WriteString("\n")
}

Typowe pułapki

  • Brak zwracania io.EOF (nieskończony odczyt)
  • Zapisywanie poza len(p)
  • Użycie odbiorcy wartości w readerach przechowujących stan

Po co tworzyć niestandardowe readery

Pozwalają one dostosować dowolne źródło — generatory, dekodery, ograniczniki szybkości i zaszyfrowane strumienie — do uniwersalnego ekosystemu wejścia-wyjścia Go.

Szybki test

Proszę sprawdzić swoją wiedzę o niestandardowych readerach.

Podsumowanie

Poznali Państwo sposób tworzenia własnych strumieni.

  • Zaimplementować Read(p []byte) (int, error)
  • Używać copy i przestrzegać len(p)
  • Zwracać io.EOF po zakończeniu odczytu
  • Używać odbiorcy wskaźnikowego w readerach przechowujących stan
  • Bez dodatkowej pracy komponować je ze wszystkimi funkcjami pomocniczymi io

Często zadawane pytania

Czy lekcja „Implementowanie własnych Readerów” jest bezpłatna?

Tak — pełny tekst „Implementowanie własnych Readerów” 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 „Implementowanie własnych Readerów”?

Buduj własne strumienie Ć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 4 z 4.

Ile czasu zajmuje lekcja „Implementowanie własnych Readerów”?

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. Interfejs Reader
  2. Interfejs Writer
  3. Funkcje pomocnicze io
  4. Implementowanie własnych Readerów
← Powrót do Go Academy