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ć
copyi przestrzegaćlen(p) - Zwracać
io.EOFpo 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
- Interfejs Reader
- Interfejs Writer
- Funkcje pomocnicze io
- Implementowanie własnych Readerów