Generics'e Giriş
Coddy'nin GO Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 67 / 107.
Go 1.18'den önce, farklı türler için yeniden kullanılabilir kod yazmak, ya fonksiyonları kopyalamak ya da tür iddialarıyla birlikte boş arayüz olan any kullanmak anlamına geliyordu. Jenerikler, tam tür güvenliğini korurken birden çok türle çalışan fonksiyonlar ve türler yazmanıza olanak tanıyarak bu sorunu çözer.
Bir dilimdeki minimum değeri bulmayı düşünün. Jenerikler olmadan her tür için ayrı işlevlere ihtiyacınız olurdu:
func MinInt(values []int) int {
min := values[0]
for _, v := range values {
if v < min {
min = v
}
}
return min
}
func MinFloat64(values []float64) float64 {
min := values[0]
for _, v := range values {
if v < min {
min = v
}
}
return min
}Jeneriklerle, köşeli parantezler içinde bir tür parametresi kullanarak mantığı bir kez yazarsınız:
func Min[T int | float64](values []T) T {
min := values[0]
for _, v := range values {
if v < min {
min = v
}
}
return min
}[T int | float64], T tür parametresinin int veya float64 olabileceğini bildirir. Artık aynı işlevi kullanarak Min([]int{3, 1, 2}) veya Min([]float64{3.5, 1.2}) çağrısını yapabilirsiniz. Derleyici türleri derleme zamanında denetlediğinden, çalışma zamanı ek yükü olmadan güvenlik elde edersiniz.
Gelecek derslerde tür parametrelerini, kısıtlamaları ve genel yapı türlerini ayrıntılı olarak inceleyeceğiz.
Görev
KolayJenerikler kullanarak hem tamsayı hem de kayan noktalı puanlarla çalışan bir puan analizcisi oluşturalım! Bir dilimdeki en büyük değeri bulabilen tek bir genel işlev oluşturacak ve farklı sayısal türler için yinelenen kod gereksinimini ortadan kaldıracaksınız.
Kodunuzu iki dosyaya ayıracaksınız:
analyzer.go: Genel analiz işlevlerinizi tanımlayın.Bir dilimdeki en büyük değeri bulup döndüren
Max[T int | float64](values []T) Tgenel işlevini oluşturun. İşlev, tür parametresiintaracılığıyla hemfloat64hem deTtürleriyle çalışmalıdır.Ayrıca bir dilimdeki tüm değerlerin toplamını hesaplayıp döndüren
Sum[T int | float64](values []T) Tgenel işlevini oluşturun.main.go: Girdiyi okuyun ve genel işlevlerinizi farklı türlerle gösterin.Bir tür göstergesi (
intveyafloat) okuyun, ardından bir sayı adedi ve bu kadar değeri okuyun. Değerleri türe göre ayrıştırın, uygun türle hemMaxhem deSumişlevlerini çağırın ve sonuçları yazdırın.Tamsayı girdisi için şunu yazdırın:
Max (int): [value] Sum (int): [value]Kayan noktalı girdi için bir ondalık basamakla yazdırın:
Max (float): [value] Sum (float): [value]
Aşağıdaki girdiler sağlanacaktır:
- 1. satır: Tür göstergesi (
intveyafloat) - 2. satır: Değerlerin adedi (tamsayı)
- Sonraki satırlar: Satır başına bir değer
Örneğin, şu verildiğinde:
int
4
15
8
23
11Çıktınız şu olmalıdır:
Max (int): 23
Sum (int): 57Ve şu verildiğinde:
float
3
4.5
9.2
6.8Çıktınız şu olmalıdır:
Max (float): 9.2
Sum (float): 20.5Aynı genel işlevlerin hem tamsayı hem de kayan noktalı verileri nasıl işlediğine dikkat edin: [T int | float64] tür parametresi, yalnızca mantığı bir kez yazarken derleyicinin her kullanım için tür güvenli kod oluşturmasına olanak tanır.
Kendin dene
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
func main() {
reader := bufio.NewReader(os.Stdin)
// Tip göstergesini oku
typeStr, _ := reader.ReadString('\n')
typeStr = strings.TrimSpace(typeStr)
// Sayıyı oku
countStr, _ := reader.ReadString('\n')
count, _ := strconv.Atoi(strings.TrimSpace(countStr))
if typeStr == "int" {
// Tamsayı değerlerini oku
values := make([]int, count)
for i := 0; i < count; i++ {
line, _ := reader.ReadString('\n')
values[i], _ = strconv.Atoi(strings.TrimSpace(line))
}
// TODO: Max ve Sum'u tamsayı dilimi ile çağır
// TODO: Sonuçları "Max (int): [value]" ve "Sum (int): [value]" formatında yazdır
} else if typeStr == "float" {
// Float değerlerini oku
values := make([]float64, count)
for i := 0; i < count; i++ {
line, _ := reader.ReadString('\n')
values[i], _ = strconv.ParseFloat(strings.TrimSpace(line), 64)
}
// TODO: Max ve Sum'u float64 dilimi ile çağır
// TODO: Sonuçları bir ondalık basamakla "Max (float): [value]" ve "Sum (float): [value]" formatında yazdır
}
}
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ı3İş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