io.Reader ve io.Writer
Coddy'nin GO Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 73 / 107.
Go'nun standart kütüphanesi, iki temel arayüz aracılığıyla arayüz tabanlı tasarımı sergiler: io.Reader ve io.Writer. Bu basit arayüzler, dosya işlemlerinden ağ iletişimine kadar her şeye güç verir.
io.Reader arayüzü yalnızca bir yöntem gerektirir:
type Reader interface {
Read(p []byte) (n int, err error)
}Dilim içine en fazla len(p) bayt okur ve kaç bayt okunduğunu döndürür. Benzer şekilde, io.Writer şunları tanımlar:
type Writer interface {
Write(p []byte) (n int, err error)
}Bu yöntemleri uygulayan herhangi bir tür, tüm G/Ç ekosistemiyle çalışır.
İşte io.Reader arayüzünü uygulayan özel bir tür:
type RepeatReader struct {
Char byte
Count int
pos int
}
func (r *RepeatReader) Read(p []byte) (int, error) {
if r.pos >= r.Count {
return 0, io.EOF
}
n := 0
for n < len(p) && r.pos < r.Count {
p[n] = r.Char
n++
r.pos++
}
return n, nil
}Artık bu özel okuyucu, io.Reader bekleyen herhangi bir işlevle çalışır:
reader := &RepeatReader{Char: 'A', Count: 5}
data, _ := io.ReadAll(reader)
fmt.Println(string(data)) // AAAAABu tasarım, io.Reader veya io.Writer kabul eden işlevler yazmanıza olanak tanır; böylece bunlar dosyalarla, ağ bağlantılarıyla, arabelleklerle veya herhangi bir özel uygulamayla çalışabilir.
Görev
Kolayio.Reader ve io.Writer arayüzlerini uygulayan özel bir metin akışı işlemcisi oluşturalım! Metin içlerinden geçerken onu dönüştürebilen türler oluşturacak ve bu temel arayüzlerin güçlü G/Ç bileşimi sağlamasını göstereceksin.
Kodunu iki dosyaya ayıracaksın:
streams.go: Özel okuyucu ve yazıcı türlerini tanımla.Bir dizeyi saran ve kaç bayt okunduğunu takip eden bir
CountingReaderyapısı oluştur. Kaynak dize ve konum izleyici alanlarına sahip olmalı. Kaynaktan sağlanan dilime baytları okuyan, konumu güncelleyen ve kaynak tükendiğindeRead(p []byte) (int, error)döndürenio.EOFmetodunu uygula.Yazılan verileri toplayan ve büyük harfe dönüştüren bir
UppercaseWriteryapısı oluştur. Birikmiş sonucu dahili olarak saklamalıdır. Gelen baytları büyük harfe dönüştüren ve saklayanWrite(p []byte) (int, error)metodunu uygula. Birikmiş büyük harfli metni almak içinResult() stringmetodunu ekle.Türlerini uygun şekilde başlatmak için
NewCountingReader(source string) *CountingReaderveNewUppercaseWriter() *UppercaseWriterkurucu işlevlerini oluştur.main.go: Özel G/Ç türlerinin standart kitaplıkla birlikte çalışmasını göster.Bir dize girdisi oku, ardından tüm verileri okumak için
CountingReadertürünüio.ReadAllile kullan. Bu verileri,UppercaseWritermetodunu kullanarakWriteüzerinden geçir.Sonuçları şu biçimde yazdır:
Original: [input] Uppercase: [result from writer] Bytes read: [total bytes]
Aşağıdaki girdi sağlanacaktır:
- Tek bir metin satırı
Örneğin, şu verildiğinde:
Hello WorldÇıktın şöyle olmalı:
Original: Hello World
Uppercase: HELLO WORLD
Bytes read: 11Ve şu verildiğinde:
Go interfaces are powerfulÇıktın şöyle olmalı:
Original: Go interfaces are powerful
Uppercase: GO INTERFACES ARE POWERFUL
Bytes read: 26Temel çıkarım şudur: CountingReader, io.ReadAll uyguladığı için io.Reader ile sorunsuz şekilde çalışır. Go ekosisteminde io.Reader kabul eden herhangi bir işlev, özel türünle çalışır: arayüz tabanlı tasarımın gücü budur.
Kendin dene
package main
import (
"bufio"
"fmt"
"io"
"os"
)
func main() {
// Girdiyi oku
reader := bufio.NewReader(os.Stdin)
input, _ := reader.ReadString('\n')
// Varsa sondaki satır sonunu kaldır
if len(input) > 0 && input[len(input)-1] == '\n' {
input = input[:len(input)-1]
}
// TODO: Girdi dizesiyle bir CountingReader oluştur
// countingReader := NewCountingReader(input)
// TODO: CountingReader'ınızdan tüm verileri okumak için io.ReadAll kullanın
// data, err := io.ReadAll(countingReader)
// TODO: Bir UppercaseWriter oluştur
// upperWriter := NewUppercaseWriter()
// TODO: Veriyi UppercaseWriter'ınıza yazın
// upperWriter.Write(data)
// TODO: Sonuçları gerekli formatta yazdırın:
// Original: [input]
// Uppercase: [writer'dan gelen sonuç]
// Bytes read: [toplam bayt]
// Kullanılmayan import hatasını önlemek için yer tutucu - uygularken kaldırın
_ = io.EOF
fmt.Println("Original:", input)
// fmt.Println("Uppercase:", upperWriter.Result())
// fmt.Println("Bytes read:", countingReader.Position)
}
Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
Nesne Yönelimli Programlama bölümündeki tüm dersler
1Go OOP Temelleri
Harici DosyalarGo Çalışma Alanı ve ModüllerPaketler ve İçe AktarmalarDışa Aktarılan ve Aktarılmayan İsimlerGo'da OOP'ye GirişSınıf Olarak Struct'larStruct'larda Metot TanımlamaPointer ve Değer AlıcılarStruct BaşlatmaYapıcı FonksiyonlarÖzet - Basit Hesap Makinesi4Arayüzler
Arayüzlere GirişÖrtük UygulamaSözleşme Olarak ArayüzBoş Arayüz (any)Tür OnaylamaTür SeçimiArayüz BileşimiStringer ve Error ArayüzleriÖzet - Şekil Hesaplayıcı7Kapsülleme
Dışa Aktarılan ve Aktarılmayan AlanlarPaket Seviyesinde KapsüllemeGetter ve Setter MetotlarıGo'da Bilgi GizlemeÖzet - Öğrenci Kayıtları10Generics (Go 1.18+)
Generics'e GirişTür ParametreleriTür KısıtlamalarıGeneric Struct'larGeneric Metotlar İçin Geçici ÇözümÖzet - Generic Koleksiyon13Tasarım Kalıpları Bölüm 1
Tasarım Kalıplarına GirişSingleton KalıbıFactory KalıbıAbstract Factory KalıbıObserver KalıbıStrategy Kalıbı2Türler ve Struct'lar: Derinlemesine İnceleme
Temel ve Bileşik TürlerÖzel Tür TanımlamalarıStruct EtiketleriAnonim Struct'larİç İçe Geçmiş Struct'larSıfır Değerler ve VarsayılanlarÖzet - Rehber5Kalıtım Yerine Kompozisyon
Go'da Neden Kalıtım YokStruct Gömme TemelleriMetot YükseltmeBirden Fazla Struct GömmeGömme vs AgregasyonGömülü Metotları GölgelemeÖzet - Çalışan Hiyerarşisi8Hata Yönetimi ve OOP
error ArayüzüÖzel Hata TürleriHata Sarmalama (fmt.Errorf)Sentinel Hatalarerrors.Is() ve errors.As()Panic, Defer ve RecoverÖzet - Dosya Ayrıştırıcı11Standart Kütüphane ve OOP
io.Reader ve io.Writersort.Interface Arayüzüfmt.Stringer ArayüzüStruct'lar ile encoding/jsonhttp.Handler ArayüzüÖzet - REST API Modelleri3İşaretçiler ve Bellek
Go'da İşaretçi TemelleriStruct İşaretçileriDeğer ile Geçme ve Referans ile Geçmenew() FonksiyonuGo'da Garbage CollectionÖzet - Linked List Oluşturucu6Go'da Polimorfizm
Interface'ler ile PolimorfizmGo'da Duck TypingInterface Karşılama KurallarıPolimorfik KoleksiyonlarDependency InjectionÖzet - Payment Processor9Eşzamanlılık ve OOP
Goroutine TemelleriKanallar ve İletişimTamponlu ve Tamponsuz KanallarSelect İfadesisync.Mutex ve sync.RWMutexsync.WaitGroupThread-Safe Struct TasarımıÖzet - Worker PoolKendi başına pratik yap: Online Go derleyicisi