0Pricing
Go Academy · Lezione

Implementare reader personalizzati

Creare i propri stream

Implementare reader personalizzati è una lezione Go Academy gratuita su CoddyKit. Questa è la lezione 4 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Go Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Go Academy include 4 lezioni in totale.

Costruire i propri flussi

Può creare sorgenti dati personalizzate implementando l'interfaccia io.Reader, composta da un solo metodo. Il Suo tipo funzionerà quindi con ogni helper di io.

Il metodo da implementare

Implementi Read(p []byte) (n int, err error) sul Suo tipo. Riempia p, restituisca il conteggio e restituisca io.EOF al termine.

Un reader costante

Qui viene mostrato un reader che emette all'infinito lo stesso byte, limitato con 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))
}

Segnalare EOF

Restituisca io.EOF quando la sorgente è esaurita. Può restituirlo da solo oppure insieme agli ultimi byte.

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))
}

Leggere da una slice

Un reader personalizzato può tenere traccia di una posizione nei dati sottostanti, restituendo un blocco a ogni chiamata.

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))
}

Un reader con trasformazione

Avvolga un altro reader e trasformi i byte al volo: in questo caso ogni byte viene convertito in maiuscolo mentre il flusso avanza.

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))
}

Rispettare la lunghezza del buffer

Non scriva mai più di len(p) byte. Utilizzi copy(p, src), che è limitato dalla slice più piccola, e restituisca il numero di byte copiati.

Receiver per valore e receiver con puntatore

Se il reader tiene traccia della posizione o dello stato, utilizzi un receiver con puntatore, così le modifiche persistono tra le chiamate. I reader senza stato possono usare un receiver per valore.

Comporre con gli helper di io

Poiché il Suo tipo soddisfa io.Reader, può essere inserito gratuitamente in io.Copy, bufio.NewReader, io.LimitReader e altri strumenti.

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")
}

Errori comuni

  • Dimenticare di restituire io.EOF (lettura infinita)
  • Scrivere oltre len(p)
  • Usare un receiver per valore per reader con stato

Perché usare reader personalizzati

Consentono di adattare qualsiasi sorgente, come generatori, decodificatori, limitatori di velocità e flussi cifrati, all'ecosistema universale di I/O di Go.

Verifica rapida

Verifichi la Sua conoscenza dei reader personalizzati.

Riepilogo

Ha imparato a costruire i propri flussi.

  • Implementare Read(p []byte) (int, error)
  • Usare copy e rispettare len(p)
  • Restituire io.EOF al termine
  • Usare un receiver con puntatore per i reader con stato
  • Comporre gratuitamente con tutti gli helper di io

Domande Frequenti

La lezione «Implementare reader personalizzati» è gratuita?

Sì — il testo completo di «Implementare reader personalizzati» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Go Academy, passa a CoddyKit PRO. Il corso Go Academy include 4 lezioni in totale.

Cosa imparerò in «Implementare reader personalizzati»?

Creare i propri stream Eserciti Go Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare Go Academy?

Non è richiesta alcuna esperienza precedente. Go Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 4 di 4.

Quanto tempo richiede la lezione «Implementare reader personalizzati»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione Go Academy?

Sì. Ogni lezione Go Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. L'interfaccia Reader
  2. L'interfaccia Writer
  3. Funzioni di utilità di io
  4. Implementare reader personalizzati
← Torna a Go Academy