Menu
Coddy logo textTech

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.

challenge icon

Görev

Kolay

Jenerikler 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) T genel işlevini oluşturun. İşlev, tür parametresi int aracılığıyla hem float64 hem de T tü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) T genel işlevini oluşturun.

  • main.go: Girdiyi okuyun ve genel işlevlerinizi farklı türlerle gösterin.

    Bir tür göstergesi (int veya float) 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 hem Max hem de Sum iş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 (int veya float)
  • 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): 57

Ve ş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.5

Aynı 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
	}
}
quiz iconKendini test et

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

Kendi başına pratik yap: Online Go derleyicisi