Menu
CoddyTech

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 işlevleri yinelemek ya da tür doğrulamalarıyla boş arayüz any kullanmak anlamına geliyordu. Jenerikler, tam tür güvenliğini korurken birden fazla türle çalışan işlevler ve türler yazmanı sağlayarak bu sorunu çözer.

Bir dilimdeki en küçük değeri bulmayı düşün. Jenerikler olmadan, her tür için ayrı işlevler yazman gerekirdi:

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], int veya float64 olabilen bir tür parametresi T tanımlar. Artık aynı işlevi kullanarak Min([]int{3, 1, 2}) veya Min([]float64{3.5, 1.2}) çağırabilirsin. Derleyici türleri derleme zamanında denetler; böylece çalışma zamanı ek yükü olmadan güvenlik sağlarsın.

Önümüzdeki derslerde tür parametrelerini, kısıtlamaları ve genel türden yapıları ayrıntılı olarak inceleyeceğiz.

challenge icon

Görev

Kolay

Jeneriklerle hem tam sayı hem de kayan noktalı puanlarla çalışan bir puan analiz aracı oluşturalım! Bir dilimdeki en büyük değeri bulabilen tek bir jenerik işlev oluşturacak ve böylece farklı sayısal türler için yinelenen kod yazma gereksinimini ortadan kaldıracaksın.

Kodunu iki dosyaya yerleştireceksin:

  • analyzer.go: Jenerik analiz işlevini tanımla.

    Bir dilimdeki en büyük değeri bulup döndüren Max[T int | float64](values []T) T adlı bir jenerik işlev oluştur. Bu işlev, tür parametresi T aracılığıyla hem int hem de float64 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 adlı bir jenerik işlev oluştur.

  • main.go: Girdiyi oku ve jenerik işlevlerini farklı türlerle göster.

    Bir tür belirtecini (int veya float) oku, ardından bir sayı ve bu sayı kadar değer oku. Değerleri türe göre ayrıştır, uygun türle hem Max hem de Sum işlevlerini çağır ve sonuçları yazdır.

    Tam sayı girdisi için şunu yazdır:

    Max (int): [value]
    Sum (int): [value]

    Kayan noktalı sayı girdisi için bir ondalık basamakla yazdır:

    Max (float): [value]
    Sum (float): [value]

Aşağıdaki girdiler sağlanacaktır:

  • 1. satır: Tür belirteci (int veya float)
  • 2. satır: Değerlerin sayısı (tam sayı)
  • Sonraki satırlar: Her satırda bir değer

Örneğin, şu girdi verildiğinde:

int
4
15
8
23
11

Çıktın şöyle olmalıdır:

Max (int): 23
Sum (int): 57

Ve şu girdi verildiğinde:

float
3
4.5
9.2
6.8

Çıktın şöyle olmalıdır:

Max (float): 9.2
Sum (float): 20.5

Aynı jenerik işlevlerin hem tam sayı hem de kayan noktalı verileri nasıl işlediğine dikkat et: [T int | float64] tür parametresi, mantığı yalnızca bir kez yazarken derleyicinin her kullanım için tür güvenli kod üretmesini sağlar.

Kendin dene

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

func main() {
	reader := bufio.NewReader(os.Stdin)

	// Tür göstergesini oku
	typeStr, _ := reader.ReadString('\n')
	typeStr = strings.TrimSpace(typeStr)

	// Sayımı 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 fonksiyonlarını tamsayı dilimiyle çağır
		// TODO: Sonuçları "Max (int): [value]" ve "Sum (int): [value]" biçiminde yazdır

	} else if typeStr == "float" {
		// Ondalıklı sayı 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 fonksiyonlarını float64 dilimiyle çağır
		// TODO: Sonuçları "Max (float): [value]" ve "Sum (float): [value]" biçiminde, virgülden sonra bir basamakla 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